Function 在函数应用程序上找不到隐式参数

Function 在函数应用程序上找不到隐式参数,function,scala,implicit-conversion,Function,Scala,Implicit Conversion,如果我定义的打印函数仅将数字作为: def print[T <% Number](value:T) {} print: [T](value: T)(implicit evidence$1: (T) => java.lang.Number)Unit 但不是用字符串: print("aaa") <console>:7: error: could not find implicit value for evidence parameter of type (java.la

如果我定义的打印函数仅将数字作为:

def print[T <% Number](value:T) {}
print: [T](value: T)(implicit evidence$1: (T) => java.lang.Number)Unit
但不是用字符串:

print("aaa")  
<console>:7: error: could not find implicit value for evidence parameter of type (java.lang.String) => java.lang.Number
       print("aaa")
打印(“aaa”)
:7:错误:找不到类型为(java.lang.String)=>java.lang.Number的证据参数的隐式值
打印(“aaa”)
这是意料之中的

但如果我将打印功能定义为:

def print2[T <% Number]: T => Unit = value => { } 
print2: [T](implicit evidence$1: (T) => java.lang.Number)(T) => Unit
def print2[T单位=值=>{}
print2:[T](隐式证据$1:(T)=>java.lang.Number)(T)=>Unit
请注意隐式参数是如何作为第一个参数而不是最后一个参数的

如果我尝试手动定义上述函数:

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 =  { }
defprint3[T](隐式f:(T)=>java.lang.Number)(值:T):单位={}
:1:错误:“=”应为“”,但找到了“(”。
def print3[T](隐式f:(T)=>java.lang.Number)(值:T):单位={}
基本上,上面的函数定义无效,但编译器在我之前定义print2时创建了它

当我使用Int调用print2时:

print2(5)
<console>:7: error: type mismatch;
 found   : Int(5)
 required: (?) => java.lang.Number
       print2(5)
print2(5)
:7:错误:类型不匹配;
发现:Int(5)
必需:(?)=>java.lang.Number
印刷品2(5)
如果我将其参数化:

print2[Int](5)
<console>:7: error: type mismatch;
 found   : Int(5)
 required: (Int) => java.lang.Number
       print2[Int](5)
print2[Int](5)
:7:错误:类型不匹配;
发现:Int(5)
必需:(Int)=>java.lang.Number
print2[Int](5)
似乎找不到scala.Int=>java.lang.Integer的隐式转换


如何重新定义print,使其以正确的方式返回函数并访问隐式函数?

这里的问题是您将5作为隐式参数传递

print2(5)
现在我在电脑上,有一些更正:

def print[T <% Number](value:T) {}
因此,在这里,您调用方法
print2
传递
5
作为其隐式参数。类型
T
尚未推断,因为它首先尝试将
5
与预期类型
T=>Number
一致。但是,由于
5
函数1[T,Number]不一致
,它甚至没有推断出
T
就失败了

有许多方法可以调用
print2
。例如:

print2(implicitly[Int => Number])
print2[Int]
(print2: Int => Unit)
val f: Int => Unit = print2
但是,要调用由
print2
返回的函数,必须避免使
(5)
看起来像方法
print2
的隐式参数。实际上,上面只有一种情况需要一些不同的东西:

print2(implicitly[Int => Number])(5)
print2[Int].apply(5)
(print2: Int => Unit)(5)
val f: Int => Unit = print2; f(5)

现在,这些例子中大多数都有明确的,而不是推断的类型参数。让我们考虑它缺席时会发生什么:

print2.apply(5)
由于未向
print2
传递任何参数,因此它会选择符合
T
边界的最特定类型。由于
T
没有边界,因此选择了
Nothing
。然后它会尝试查找隐式
Nothing=>单元
。由于没有此类隐式,因此失败


print2
将返回的函数参数从未被用于帮助类型推断。

您将方法与函数混淆。了解它们的差异。搜索堆栈溢出。我在手机上,因此很难查找引用。我认为这可能是
scalac实现。如果您仔细想想,除了端点之外的任何位置的隐式参数都没有意义。假设这是允许的
def foo(隐式i:Int)(j:Float)(隐式:k:Int)(l:Double)=…
。它对应用程序
foo(1)(2)(3)到底意味着什么
?有点含糊不清。我同意。隐式应该是最后一个参数。如何调用print2以使用隐式参数?我可以像这样调用它:print2(隐式[Int=>java.lang.Number])(5)。这不是最好的解决方案。@ssanj您可以使用print2[Int]。apply(5),虽然我意识到这不太可能是你想要的。但是,你希望语言以一种它不想要的方式工作。
print2(implicitly[Int => Number])(5)
print2[Int].apply(5)
(print2: Int => Unit)(5)
val f: Int => Unit = print2; f(5)
print2.apply(5)