Kotlin学习之泛型函数和星投影

    技术2023-11-07  105

     泛型函数

    和Java类型,除了泛型类,函数本身也是支持泛型的。

    fun <T> getValue(item: T): T { return item }

    普通的函数是没有<T>这部分内容的,表示这个是泛型函数,拥有一个泛型类型T。

    val item = getValue<Int>(100)

     泛型约束

    定义好一个泛型,在声明泛型类的时候指定好泛型的上界。

    class UpperBoundeClass<T : List<T>> { }

    指定UpperBoundeClass的泛型是T,要求T只能是列表List以及List下面的类型。

    星投影

    对于 Foo <out T : TUpper>,其中 T 是一个具有上界 TUpper 的协变类型参数,Foo <*> 等价于 Foo <out TUpper>。 这意味着当 T 未知时,你可以安全地从 Foo <*> 读取 TUpper 的值。

    class Star <out T>{ } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main9) val star1 : Star<Number> = Star<Int>() val star2 :Star<*> = star1 }

    star1具有上界Number,Star<*>等价于Star <out Number>。如果读取star2 ,这里的star2的类型都是Number类型。

    对于 Foo <in T>,其中 T 是一个逆变类型参数,Foo <*> 等价于 Foo <in Nothing>。 这意味着当 T 未知时,没有什么可以以安全的方式写入 Foo <*>。

    class Star2 <in T>{ fun setValue(t:T){ } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main9) val star2 :Star2<Int> = Star2<Number>() val star3 :Star2<*> = star2 star3.setValue(3)//编译报错 }

    对于 Foo <T : TUpper>,其中 T 是一个具有上界 TUpper 的不型变类型参数,Foo<*> 对于读取值时等价于 Foo<out TUpper> 而对于写值时等价于 Foo<in Nothing>。

    class Star3<T>(private var t: T) { fun setValue(t: T) { } fun getValue(): T { return this.t } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main9) val star3: Star3<String> = Star3<String>("hello") val star4: Star3<*> = star3 star4.getValue() star4.setValue("world")//编译错误 }

     

     无法编译通过,道理和之前的是类型的。

    Processed: 0.019, SQL: 9