代码之家  ›  专栏  ›  技术社区  ›  Bogdan Vakulenko

抽象类型成员的类型推理

  •  0
  • Bogdan Vakulenko  · 技术社区  · 7 年前
    val s1: ({type T <: String})#T = "some string" // failed
    
    val s2: ({type T = String})#T = "some string" // compiled
    

    为什么第一行编译失败?为什么? T

    编辑:

    )

    trait K {
      type T <: String
      val s1:T = "some string" // failed
    }
    

    type  K  = {type T <: String}
    
    val s1:K#T = "some string" // failed
    
    def test(in: K#T):K#T = in // can be used as output type as well
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   Dmytro Mitin    7 年前

    k.T 是一个 path-dependent type . 每种情况都可能不同 k 属于 K

    trait K {
      type T <: String
      val s1: T /*= "some string"*/
    }
    
    object K1 extends K {
      override type T = Null
      override val s1 = null
    }
    
    object K2 extends K {
      override type T = Nothing
      override val s1 = ???
    }
    
    object K3 extends K {
      override type T = String with Int
      override val s1 = ???
    }
    
    
    object K4 extends K {
      override type T = shapeless.Witness.`"some other string"`.T
      override val s1 = "some other string"
    }
    
    object K5 extends K {
      // K5.T is abstract
      override val s1 = ???
    }
    
    object K6 extends K {
      // K6.T is abstract but different from K5.T
      override val s1 = ???
    }
    
        2
  •  4
  •   jwvh    7 年前

    我认为这与收益(结果)类型的方差关系有关。

    注意 T 作为输入接受 String

    def s3[T <: String](s:T) = "some string" // T as input
    s3("blah")  //input T = String
    

    ... 但不是作为输出 .

    def s3[T <: String](s:T):T = "some string" // fails to compile
    //                      ^^^
    

    T -至- 字符串 关系和这个工作。。。

    def s3[T >: String](s:T):T = "some string" // T as input and output
    s3("blah")
    

    val s1: ({type T >: String})#T = "some string" // good
    
        3
  •  2
  •   Alexey Romanov    7 年前

    问题不是这样的 T 不能是字符串,但它可能是字符串无法分配的其他对象(例如。 Null Nothing ).

    推荐文章