two type parameters with the same name

前端 未结 4 762
野趣味
野趣味 2021-01-02 23:44

I am wondering why the two type parameters (named \"A\") with the same name (\"A\") is allowed as per the example below. I know this is a POOR naming of type parameters, do

4条回答
  •  长发绾君心
    2021-01-03 00:11

    I'm not expert of Scala, but your code behave exactly what I would expected.

    First, you need to know that the type parameter of method is not need bound to class.

    For example, the following is valid Scala.

    class Test1 {
        def test[A] (x: A) = println(x)
    }
    

    And the following is also a valid Scala code, the only different is that this one does not use the type A at all.

    class Test2[A] {
        def test (x: Int) = println(x)
    }
    

    So I think it is clear now, first you created a instance of MyTest[Int], which is fine.

    scala> val test = new MyTest[Int]
    test: MyTest[Int] = MyTest@308ff65f
    

    Then you called checkString[A, Int] without provide type parameter A, since it is a generic function, the compiler must inference what type is A.

    scala> test.checkString("String",1)
    Value is a String
    x is not a String
    res7: java.lang.String = String
    

    Note:

    In this time point, Scala already knows that x must be a Int and its type is fixed, since you provide it by MyTest[Int]. So the following code will yield compile error.

    scala> val t = new MyTest[Int]
    t: MyTest[Int] = MyTest@cb800f
    
    scala> t.checkString ("A", "B")
    :8: error: type mismatch;
     found   : java.lang.String("B")
     required: t.MyType
           t.checkString ("A", "B")
    

    Now the complier looks at the arguments you provided, and found its is

    checkString ("String", 1)
    

    which is corresponding to

    checkString (value: A, x: Int)
    

    So now compiler knows type A in checkString[A, Int] must be a string, and if you do all of this by hand, your code will look like this.

    scala> val test = new MyTest[Int]
    test: MyTest[Int] = MyTest@5bda13
    
    scala> test.checkString[String]("String", 1)
    Value is a String
    x is not a String
    res1: String = String
    
    scala> test.checkString[Int] (3, 4)
    Value is not a String
    x is not a String
    res4: Int = 3
    
    scala> test.checkString[Int] ("String", 4)
    :8: error: type mismatch;
     found   : java.lang.String("String")
     required: Int
           test.checkString[Int] ("String", 4)
                              ^    
    

提交回复
热议问题