Scala 类型别名,包括伴生对象 [初学者]

发布于 2024-09-27 08:58:07 字数 830 浏览 1 评论 0原文

我想编写一个类型别名来缩短、美观和封装 Scala 代码。 假设我得到了一些集合,它具有映射列表的属性,其值是元组。 我的类型会编写类似于 List[Map[Int, (String, String)]] 的内容,或者我的应用程序允许的任何更通用的内容。我可以想象有一个超类型要求一个 Seq[MapLike[Int, Any]] 或任何让我满意的东西,而具体的子类则更具体。

然后我想为这个长类型编写一个别名。

class ConcreteClass {
  type DataType = List[Map[Int, (String, String)]]
  ...
}

然后,我会很乐意在任何可以使用的地方使用 ConcreteClass#DataType 并使用它。

现在假设我添加一个函数

def foo(a : DataType) { ... }

并且我想用一个空列表从外部调用它。 我可以调用 foo(List()) ,但是当我想将基础类型更改为另一种类型的 Seq 时,我必须返回并更改它代码也。此外,这个空列表作为 DataType 的用途并不是很明确。并且伴随对象没有关联的 List 方法,因此我无法调用 DataType()DataType.empty。当我需要非空列表时,这会更烦人,因为我必须写出这个长类型的重要部分。

有什么方法可以让 Scala 将我的类型理解为同一事物,包括伴随对象及其创建者方法,以缩短代码并将其黑盒化? 或者,有什么理由让我一开始就不应该这样做?

I'd like to write a type alias to shorten, nice and encapsulated Scala code.
Suppose I got some collection which has the property of being a list of maps, the value of which are tuples.
My type would write something like List[Map[Int, (String, String)]], or anything more generic as my application allows it. I could imagine having a supertype asking for a Seq[MapLike[Int, Any]] or whatever floats my boat, with concrete subclasses being more specific.

I'd then want to write an alias for this long type.

class ConcreteClass {
  type DataType = List[Map[Int, (String, String)]]
  ...
}

I would then happily use ConcreteClass#DataType everywhere I can take one, and use it.

Now suppose I add a function

def foo(a : DataType) { ... }

And I want to call it from outside with an empty list.
I can call foo(List()), but when I want to change my underlying type to be another type of Seq, I'll have to come back and change this code too. Besides, it's not very explicit this empty list is intended as a DataType. And the companion object does not have the associated List methods, so I can't call DataType(), or DataType.empty. It's gonna be even more annoying when I need non-empty lists since I'll have to write out a significant part of this long type.

Is there any way I can ask Scala to understand my type as the same thing, including companion object with its creator methods, in the interest of shortening code and blackboxing it ?
Or, any reason why I should not be doing this in the first place ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

病毒体 2024-10-04 08:58:07

答案实际上非常简单:

class ConcreteClass {
  type DataType = List[String]
}
object ConcreteClass {
  val DataType = List
}
val d = ConcreteClass.DataType.empty

这使我的代码能够调用 ConcreteClass.DataType 来使用 List 中的所有方法构造列表,并且只需很少的努力。

非常感谢奥列格的见解。如果您不想委托 List 任何对 ConcreteClass.DataType 的调用,而是精确控制您希望允许调用者执行的操作,他的答案也是最好的。

The answer was actually quite simple:

class ConcreteClass {
  type DataType = List[String]
}
object ConcreteClass {
  val DataType = List
}
val d = ConcreteClass.DataType.empty

This enables my code to call ConcreteClass.DataType to construct lists with all the methods in List and little effort.

Thanks a lot to Oleg for the insight. His answer is also best in case you want not to delegate to List any call to ConcreteClass.DataType, but control precisely what you want to allow callers to do.

淡淡的优雅 2024-10-04 08:58:07

这又如何呢?
<代码>

class ConcreteClass {
  type DataType = List[String]
}
object DataType {
  def apply(): ConcreteClass#DataType = Nil
}
//...
val a = DataType()

What about this?

class ConcreteClass {
  type DataType = List[String]
}
object DataType {
  def apply(): ConcreteClass#DataType = Nil
}
//...
val a = DataType()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文