为什么 Scala 辅助构造函数中不允许使用类型参数?
假设我正在 Scala 中定义一个简单的 2D 点类,并且我希望能够使用各种类型来构造它:
class Point(x:Float, y:Float) {
this(x:Double, y:Double) = this(x.toFloat, y.toFloat)
this(x:Int, y:Int) = this(x.toFloat, y.toFloat)
// etc...
}
我想使用模板将其归结为以下内容:
class Point(x:Float, y:Float) {
this[T](x:T, y:T) = this(x.toFloat, y.toFloat)
}
我知道这无论如何都行不通,因为 T可能是未定义 toFloat 的类型,但我得到的编译器错误是:
此处不允许使用类型参数
这是 Scala 不支持的吗?如果是这样,为什么,有什么简单的方法可以解决这个问题吗?
Say I'm defining a simple 2D point class in Scala, and I want to be able to construct it with various types:
class Point(x:Float, y:Float) {
this(x:Double, y:Double) = this(x.toFloat, y.toFloat)
this(x:Int, y:Int) = this(x.toFloat, y.toFloat)
// etc...
}
I want to boil this down using a template, such as:
class Point(x:Float, y:Float) {
this[T](x:T, y:T) = this(x.toFloat, y.toFloat)
}
I know this won't work anyway, since T could be a type for which toFloat isn't defined, but the compiler error I get is:
no type parameters allowed here
Is this just unsupported in Scala? If so, why, and is there any simple way to get around this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Scala 的类构造函数(与 Java 不同)不能采用类型参数,只有类本身可以。至于为什么 Scala 做出这样的设计选择,我认为主要原因是简单。
如果您想要一个通用的辅助“构建器”方法,那么自然要做的就是在伴随对象上定义它。例如,
这里我使用
Numeric
类型类来获取通用toFloat
方法。Scala's class constructors (unlike Java's) can't take type parameters, only the class itself can. As to why Scala made this design choice, I assume the main reason is simplicity.
If you want a secondary "builder" method that is generic, the natural thing to do is define it on the companion object. For example,
Here I've used the
Numeric
typeclass to get a generictoFloat
method.我玩了一段时间,变得“接近”...
...这导致“错误:此处不允许类型参数”(正如帖子所述),然后我意识到...
如果初始化器可以采用类型参数,如果有的话,它与类参数会产生歧义。并不是说这个不能在语言规范中解决......但它是一个更复杂的至少是这样的情况。还可能存在 Java 互操作性问题。
想象一下:
我个人希望 Scala 遵循类似 Eiffel 的模式(仅命名构造函数或“工厂方法”),但可惜,这不是 Scala。
快乐编码。
I played with this for awhile, getting as "close" as...
...which results in "error: no type parameters allowed here" (just as per the post) and then I realized...
If the initializer could take type parameters it would be ambiguous with the class parameters, if any. Not that this couldn't be worked about in the language specification... but it is a more complex case at the very least. There might also be Java interoperability issues.
Imagine:
Personally I wish Scala followed an Eiffel-like pattern (only named constructors or "factory methods"), but alas, that would not be Scala.
Happy coding.