【问题标题】:Representing subtype relationship with <: and <:< in Scala在 Scala 中用 <: 和 <:< 表示子类型关系
【发布时间】:2023-03-23 09:11:01
【问题描述】:

通常,我使用 <: a b predef.scala>

A &lt;:&lt; B 的实例证明AB 的子类型。要求 A &lt;:&lt; B 类型的隐式参数对广义约束 A &lt;: B 进行编码。

鉴于两者都代表相同的“子类型”关系(AFAIK),请有人澄清一下两者之间的区别。另外,请建议它们的正确用法(我的意思是,<:>

【问题讨论】:

    标签: scala


    【解决方案1】:

    [A &lt;: B] 声明了一个类型参数 A,具有已知的属性/限制:它必须是类型 B(现有类型)或其子类型。

    class A  // A and B are unrelated
    class B
    
    // these both compile
    def f1[A <: B]() = ???  // A is the type parameter, not a reference to class A
    def f2[B <: A]() = ???  // B is the type parameter, not a reference to class B
    

    [A &lt;:&lt; B] 用于测试现有类型。

    class B
    class A extends B
    
    // A and B must already exist and have this relationship or this won't compile
    implicitly[A <:< B]
    

    【讨论】:

    • 您知道我们在以下情况下使用它们有什么区别吗:def test1[A &lt;: B, B] ()def test2[A, B] (implicit w: A &lt;:&lt; B) ?从编译器的角度来看,它看起来非常相似
    • @BogdanVakulenko;是的,据我所知,结果是一样的。 test2 确实通过查找隐式并将其放置在本地名称空间 w 中的努力。因此,除了更冗长之外,它还可能效率较低。
    • 我想用一个指向this post 的链接来补充这个答案,它非常详细地解释了为什么&lt;:&lt; 存在以及何时有用。 TL;博士;有时,类型约束无法证明复杂的限制——导致编译错误或错误的推断类型。在这些情况下,&lt;:&lt; 通常能够产生所需的结果。诀窍是&lt;:&lt;的参数类型信息已经解决,相反,&lt;:的参数类型信息正在解决。
    猜你喜欢
    • 2012-01-12
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 2023-04-02
    相关资源
    最近更新 更多