Sta*_*tas 4 java scala javafx javafx-2
尝试使用Scala 2.8.1/JavaFx 2.0 beta编译以下代码时
new KeyValue(circle.translateYProperty, random() * height)
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
[error] found : javafx.beans.property.DoubleProperty
[error] required: javafx.beans.value.WritableValue[Any]
[error] new KeyValue(circle.translateYProperty, random() * height)
[error] ^
[error] one error found
Run Code Online (Sandbox Code Playgroud)
虽然这行编译得很好:
new KeyValue(circle.translateXProperty.asInstanceOf[WritableValue[Any]], random() * width)
Run Code Online (Sandbox Code Playgroud)
我检查了KeyValue构造函数,它具有以下签名:
public <T> KeyValue(javafx.beans.value.WritableValue<T> tWritableValue, T t) { /* compiled code */ }
Run Code Online (Sandbox Code Playgroud)
circle.translateXProperty返回DoubleProperty,它实现以下接口:
public interface WritableNumberValue extends javafx.beans.value.WritableValue<java.lang.Number>
Run Code Online (Sandbox Code Playgroud)
什么比铸造更优雅的解决方案,使其编译?
- 基于Exception和Blaisorblade评论的修订答案 -
您已经达到了Scala应用implicits的限制,而不是(仅仅)Scala-Java互操作问题.这是一个简化的例子,
class Foo[T]
def f[T](x: Foo[T], y: T): T = y
f(new Foo[Number], new java.lang.Double(0)) // OK; infers T==Number
f[Number](new Foo[Number], 0) // OK; uses implicit int2Integer(0)
// f(new Foo[Number], 0) // error
Run Code Online (Sandbox Code Playgroud)
第一个电话f,因为共同的超类型的作品java.lang.Double,并java.lang.Number是java.lang.Number,这样的推断类型T.
第二次调用是f因为我们明确地告诉编译器T==java.lang.Number.当编译器发现的第二个参数,0 : Int不匹配预期类型java.lang.Number时,它搜索从隐式转换Int到Number.编译器查找Predef.int2Integer并应用它.一切都很好.
第三个调用f不起作用,因为第一个参数约束T == Number,第二个参数表示T >: Int(即,T是超类型Int).常见的超类型Int和Number是Any,但是这不会起作用,因为Foo[T]它不是协变的T(换句话说,我们不能把a转换Foo[Number]为a Foo[Any]).这是编译器错误消息的要点.请注意,编译器不知道如何应用隐式转换,因为它不知道T要转换的特定类型.
您发布的JavaFX代码的一个奇怪之处在于KeyValue该类不是通用的,而是具有通用构造函数.有趣的是,这是不是可能在Scala中,所以没有办法(据我可以告诉),明确约束参数T从Scala代码.如果整个KeyValue班级都是通用的,那么你也可以写作
new KeyValue[Number](circle.translateYProperty, random() * height)
Run Code Online (Sandbox Code Playgroud)
这将等同于Exception发布的代码,因为编译器会推断double2Double转换.