函数应用程序中未找到隐式参数

发布于 2024-10-18 09:26:06 字数 1463 浏览 3 评论 0原文

如果我定义一个只接受数字的打印函数:

def print[T <% Number](value:T) {}
print: [T](value: T)(implicit evidence$1: (T) => java.lang.Number)Unit

我可以使用以下方式调用上面的内容:

print(5)
print(5.5)
print(6L) 

但不能使用字符串:

print("aaa")  
<console>:7: error: could not find implicit value for evidence parameter of type (java.lang.String) => java.lang.Number
       print("aaa")

这是预期的。

但是如果我将 print 函数定义为:

def print2[T <% Number]: T => Unit = value => { } 
print2: [T](implicit evidence$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 =  { }

基本上上面的函数定义不是有效的函数定义,但编译器在我之前定义 print2 时创建了它。

当我用 Int 调用 print2 时:

print2(5)
<console>:7: error: type mismatch;
 found   : Int(5)
 required: (?) => java.lang.Number
       print2(5)

如果我参数化它:

print2[Int](5)
<console>:7: error: type mismatch;
 found   : Int(5)
 required: (Int) => java.lang.Number
       print2[Int](5)

看起来它无法找到来自 scala.Int => 的隐式转换; java.lang.Integer。

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

If I define a print function that only takes numbers as:

def print[T <% Number](value:T) {}
print: [T](value: T)(implicit evidence$1: (T) => java.lang.Number)Unit

I can call the above with:

print(5)
print(5.5)
print(6L) 

But not with a String:

print("aaa")  
<console>:7: error: could not find implicit value for evidence parameter of type (java.lang.String) => java.lang.Number
       print("aaa")

This is expected.

But if I define the print function as:

def print2[T <% Number]: T => Unit = value => { } 
print2: [T](implicit evidence$1: (T) => java.lang.Number)(T) => Unit

Notice how the implicit parameter is the first parameter instead of the last.

If I try to manually define the above function:

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 =  { }

Basically the above is not a valid function definition but the compiler creates it when I previously defined print2.

When I call print2 with an Int:

print2(5)
<console>:7: error: type mismatch;
 found   : Int(5)
 required: (?) => java.lang.Number
       print2(5)

if I parameterize it:

print2[Int](5)
<console>:7: error: type mismatch;
 found   : Int(5)
 required: (Int) => java.lang.Number
       print2[Int](5)

It looks like it can't find the implicit conversion from scala.Int => java.lang.Integer.

How can I redefine print such that it returns functions and also accesses implicits in the correct way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↙温凉少女 2024-10-25 09:26:06

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

现在我在计算机上,进行一些更正:

def print[T <% Number](value:T) {}

您称其为函数,但它是方法

def print2[T <% Number]: T => Unit = value => { }

同样,您将其称为函数。实际上,它是一个方法返回一个函数。该方法接收一个类型参数 T 和一个隐式参数。

print2(5)

因此,在这里,您调用方法 print2,并传递 5 作为其隐式参数。类型 T 尚未被推断,因为它首先尝试使 5 符合预期类型 T =>;编号。但是,由于 5 不符合 Function1[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 返回的函数参数来帮助类型推断。

The problem here is that you are passing 5 as the implicit parameter.

Now that I'm on a computer, a few corrections:

def print[T <% Number](value:T) {}

You call this a function, but it is a method.

def print2[T <% Number]: T => Unit = value => { }

Again, you call this a function. Actually, it is a method which returns a function. The method receives one type parameter, T, and one implicit parameter.

print2(5)

So, here, you call the method print2 passing 5 as its implicit parameter. The type T hasn't been infered yet because it is first trying to conform 5 to the expected type T => Number. However, since 5 doesn't conform to Function1[T, Number], it fails without even inferring T.

There are many ways to call print2. For example:

print2(implicitly[Int => Number])
print2[Int]
(print2: Int => Unit)
val f: Int => Unit = print2

However, to call the function that is returned by print2, you have to avoid making (5) look like the implicit parameter to the method print2. There's actually only one case above that needs something different:

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

Now, most of these examples have explicit, instead of inferred, type parameters. Let's consider what would happen in its absence:

print2.apply(5)

Because no parameter was passed to print2, it selects the most specific type that conforms to the bounds of T. Since T has no bounds, Nothing is chosen. It then tries to find an implicit Nothing => Unit. Because there's no such implicit, it fails.

The parameter to the function that would be returned by print2 is never looked into to help type inference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文