ssa*_*anj 5 scala function implicit-conversion
如果我定义仅将数字作为以下内容的打印功能:
def print[T <% Number](value:T) {}
print: [T](value: T)(implicit evidence$1: (T) => java.lang.Number)Unit
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式致电上述内容:
print(5)
print(5.5)
print(6L)
Run Code Online (Sandbox Code Playgroud)
但不能使用字符串:
print("aaa")
<console>:7: error: could not find implicit value for evidence parameter of type (java.lang.String) => java.lang.Number
print("aaa")
Run Code Online (Sandbox Code Playgroud)
这是预期的。
但是,如果我将打印功能定义为:
def print2[T <% Number]: T => Unit = value => { }
print2: [T](implicit evidence$1: (T) => java.lang.Number)(T) => Unit
Run Code Online (Sandbox Code Playgroud)
注意隐式参数是第一个参数而不是最后一个参数。
如果我尝试手动定义以上功能:
def print3[T](implicit f: (T) => java.lang.Number)(value:T):Unit = { }
<console>:1: error: '=' expected but '(' found.
def print3[T](implicit f: (T) => java.lang.Number)(value:T):Unit = { }
Run Code Online (Sandbox Code Playgroud)
基本上,以上不是有效的函数定义,但是编译器在我先前定义print2时创建了它。
当我用Int调用print2时:
print2(5)
<console>:7: error: type mismatch;
found : Int(5)
required: (?) => java.lang.Number
print2(5)
Run Code Online (Sandbox Code Playgroud)
如果我将其参数化:
print2[Int](5)
<console>:7: error: type mismatch;
found : Int(5)
required: (Int) => java.lang.Number
print2[Int](5)
Run Code Online (Sandbox Code Playgroud)
似乎找不到来自scala.Int => java.lang.Integer的隐式转换。
如何重新定义print以使其返回函数并以正确的方式访问隐式?
这里的问题是您要传递5 作为隐式参数。
现在,我在计算机上,进行了一些更正:
def print[T <% Number](value:T) {}
Run Code Online (Sandbox Code Playgroud)
您将其称为函数,但这是一种方法。
def print2[T <% Number]: T => Unit = value => { }
Run Code Online (Sandbox Code Playgroud)
同样,您将此称为函数。其实,这是一个方法,其返回的功能。该方法接收一个类型参数T,和一个隐式参数。
print2(5)
Run Code Online (Sandbox Code Playgroud)
因此,在这里,您将print2传递的方法5称为隐式参数。T尚未推断出类型,因为它首先尝试符合5期望的类型T => Number。但是,由于5不符合Function1[T, Number],因此即使不进行推断也会失败T。
有很多打电话的方法print2。例如:
print2(implicitly[Int => Number])
print2[Int]
(print2: Int => Unit)
val f: Int => Unit = print2
Run Code Online (Sandbox Code Playgroud)
但是,要调用返回的函数,print2必须避免使方法(5)看起来像隐式参数print2。实际上,上面只有一种情况需要不同的东西:
print2(implicitly[Int => Number])(5)
print2[Int].apply(5)
(print2: Int => Unit)(5)
val f: Int => Unit = print2; f(5)
Run Code Online (Sandbox Code Playgroud)
现在,这些示例大多数都具有显式(而不是推断的)类型参数。让我们考虑一下如果没有它会发生什么:
print2.apply(5)
Run Code Online (Sandbox Code Playgroud)
由于没有参数传递给print2它,因此它选择符合界限的最具体类型T。由于T没有界限,Nothing所以选择。然后尝试查找隐式Nothing => Unit。因为没有这样的隐式,所以失败了。
print2永远不会寻找函数返回的参数来帮助类型推断。
| 归档时间: |
|
| 查看次数: |
2621 次 |
| 最近记录: |