这是我的代码段:
implicit def trick(s: String): String = s.toUpperCase
def fun(s: String)(implicit f: String => String): String = f(s)
println(s"String is ${fun("abc")}")
当我运行它时,它打印“abc”而不是“ABC”。我在这里做错了什么?
PS 的
但是,如果我运行下一个代码
implicit val n: Int = 100
def add(n1: Int)(implicit n2: Int) = n1 + n2
add(7)
所有隐含的魔法都可以正常工作。
答案 0 :(得分:7)
通常这会奏效。编译器会通过eta-expansion隐式地将隐式方法转换为函数。比如说,如果我出于某种原因需要隐式@model Person
@using (Html.BeginForm())
{
for(int i = 0; i < Model.Cars.Count; i++)
{
@Html.HiddenFor(m => m.Cars[i].ID)
....
}
<input type="submit" value="Grant Access" />
}
。
Int => List[Int]
但是你的问题是另一个隐式implicit def trick(i: Int): List[Int] = List.fill(5)(i)
def fun(i: Int)(implicit f: Int => List[Int]): List[Int] = f(i)
scala> fun(4)
res5: List[Int] = List(4, 4, 4, 4, 4)
已经在来自String => String
的范围内。即Predef
,其扩展为=:=[String, String]
。因为这已作为函数存在于范围中,所以编译器不需要查找任何其他内容。 和,如果将隐式方法转换为隐式函数,则会出现含糊不清的错误:
String => String
实际上,拥有一个隐含的implicit val trick: String => String = _.toUpperCase
scala> fun("abc")
<console>:19: error: ambiguous implicit values:
both method $conforms in object Predef of type [A]=> <:<[A,A]
and value trick of type => String => String
match expected type String => String
fun("abc")
可能不是一个好主意。请改为使用包装函数的类型类。
String => String