【问题标题】:Understanding implicit <:< parameter理解隐式 <:< 参数
【发布时间】:2016-08-14 15:20:18
【问题描述】:

这个例子是我写的

class TestMatch[T](private val t: T){
    def test()(implicit ev: T <:< Option[Int]) = println(ev(t).get)
}

并对其进行测试

val tm = TestMatch(Some(10))
tm.test() //fine

val tm2 = TestMatch(10)
tm2.test() //compilation error

问题是当我调用test 方法时谁创建了implicit ev: T &lt;:&lt; Option[Int]?我知道我没有。也许编译器知道implicit &lt;:&lt; 并且知道如何处理它。

&lt;:&lt;的文档不太清楚

在方法的范围内约束任何抽象类型 T 参数列表(不仅仅是方法自己的类型参数)只需添加 类型的隐式参数 T &lt;:&lt; U,其中U 是必需的 上限;或者对于下限,使用:L &lt;:&lt; T,其中L 是 要求的下限。

这是否意味着编译器将自行承担其余的工作?我只是添加implicit ev: T1 &lt;:&lt; T2?

【问题讨论】:

  • 根据您最近发布的问题,您似乎在 Scala 知识方面存在一些明显的差距。我建议你阅读一本关于 Scala 语言和 Scala 编程的好书。

标签: scala implicit


【解决方案1】:

第一个 sn-p 编译是因为 Predef.identity,这意味着您始终可以将类型 T 隐式转换为类型 T(在本例中为 Option[Int])。否则,您需要自己将隐式带入范围。

【讨论】:

    【解决方案2】:

    这是否意味着编译器将自行承担其余的工作?

    编译器将搜索隐式范围。如果找到匹配项,它将提供它,如果找不到,您将收到编译错误。在您的示例中,编译器发现 Some[Int] 符合 Some[Int] &lt;:&lt; Option[Int] 的隐式要求,因为它是 Option[Int] 的直接子类型。

    使用scalac编译代码时可以看到:

    val tm: TestMatch[Some[Int]] = new TestMatch[Some[Int]](scala.Some.apply[Int](10));
    tm.test()(scala.this.Predef.$conforms[Some[Int]]);
    

    Int(您的第二个示例)在哪里,范围内没有隐式匹配要求,Int 不是Option[Int] 的子类型。

    【讨论】:

    • 知道为什么添加这种东西不起作用吗? implicit def nonZeroInt(i: Int): Option[Int] = if (i == 0) None else Some(i)(我在调用test的同一级别添加)
    【解决方案3】:

    编译器会尝试在各种预定义的地方寻找隐式参数。如果找不到它们,它将引发错误。此链接可能会有所帮助:http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html

    【讨论】:

    • 这几乎是一个仅链接的答案
    • 好的,如果你愿意,我可以删除它。我认为通过此图像可以更轻松地查看编译器隐式查找的所有位置,而不必键入它们。
    • 我认为该链接很有用,但您应该尝试为其添加一些价值。不要只为我删除你的答案:p
    猜你喜欢
    • 1970-01-01
    • 2015-08-30
    • 2018-09-23
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多