当前位置: 首页 > news >正文

凡科网做网站靠谱吗ebay欧洲站网址

凡科网做网站靠谱吗,ebay欧洲站网址,美国做任务挣钱的网站,在线做漫画网站类可以有类型参数 class Box<T>(t: T) {var value t }要创建类实例&#xff0c;需提供类型参数 val box: Box<Int> Box<Int>(1)如果类型可以被推断出来&#xff0c;可以省略 val box Box(1)通配符 在JAVA泛型中有通配符?、? extends E、? super E&…

类可以有类型参数

class Box<T>(t: T) {var value = t
}

要创建类实例,需提供类型参数

val box: Box<Int> = Box<Int>(1)

如果类型可以被推断出来,可以省略

val box = Box(1)

通配符

在JAVA泛型中有通配符?? extends E? super E,在kotlin中没有这个概念,取而代之的是Declaration-site variancetype projections

Declaration-site variance

out 协变

对于如下代码

interface Source<T> {fun next():T
}fun demo(x : Source<Number>){val objects: Source<Any> = x
}

编译器报错 – 类型不匹配
在这里插入图片描述

想要代码成立需要在泛型定义时使用out

interface Source<T> {fun next():T
}fun demo(x : Source<Number>){val objects: Source<Any> = x
}

in 逆变

对于代码

interface Comparable<T> {operator fun compareTo(other: T): Int
}fun demo(x: Comparable<Number>) {x.compareTo(1.0)val y: Comparable<Int> = x
}

报错类型不匹配
在这里插入图片描述
想要代码成立需要在泛型定义时使用in

interface Comparable<in T> {operator fun compareTo(other: T): Int
}fun demo(x: Comparable<Number>) {x.compareTo(1.0)val y: Comparable<Int> = x
}

如果T类型作为参数(消费)就是用in,如果作为返回值(生产)就用out
Consumer in, Producer out!
逆变就是大类型变小类型,协变就是小类型变大类型

type projections(类型投影)

Use-site variance: type projections(使用点位变异:类型投影)

对于以下代码

class Demo<T>{fun copy(from: Array<T>, to: Array<T>) {assert(from.size == from.size)for (i in from.indices) {to[i] = from.get(i)}}
}fun main() {val str: Array<String> = arrayOf("hello", "world")val obj: Array<Any> = arrayOf(123, 432)Demo<Any>().copy(str, obj)
}

报错
在这里插入图片描述
在类声明时,不管是使用class Demo<in T>还是class Demo<out T>都会报错,为解决这种情况,可以修改copy方法的from参数类型为from: Array<out T>,因为from作为生产者,生产数组中的值

class Demo<T>{fun copy(from: Array<out T>, to: Array<T>) {assert(from.size == from.size)for (i in from.indices) {to[i] = from.get(i)}}
}

当然也可以改成下边写法

class Demo<T>{fun copy(from: Array<T>, to: Array<in T>) {assert(from.size == from.size)for (i in from.indices) {to[i] = from.get(i)}}
}fun main() {val str: Array<String> = arrayOf("hello", "world")val obj: Array<Any> = arrayOf(123, 432)Demo<String>().copy(str, obj)
}

星号投影(*)

有时候参数是一个泛型类型,但是在定义方法的时候不能确定泛型的具体类型,需要用到*投影
语法如下

  • 对于泛型类型Foo<out T : TUpper>T是一个具有上界TUpper的协变类型参数,Foo<*>等价于Foo<out TUpper>。这意味着当T未知时,你可以安全地从Foo<*>中读取TUpper的值。
  • 对于泛型类型Foo<in T>T是一个逆变类型参数,Foo<*>等价于Foo<in Nothing>。这意味着当T未知时,你无法以安全的方式向Foo<*>写入任何值。
  • 对于泛型类型Foo<T : TUpper>T是一个不变类型参数,具有上界TUpperFoo<*>在读取值时等价于Foo<out TUpper>,在写入值时等价于Foo<in Nothing>

举个例子

class Box<out T : Any>(private val value: T) {fun getValue(): T {return value}
}fun printBoxValue(box: Box<*>) {val value = box.getValue()println(value)
}fun main(){printBoxValue(Box(123)) // 123printBoxValue(Box("hello world"))   // hello world
}

printBoxValue方法的参数使用*投影

如果一个泛型类型有多个类型参数,每个参数可以独立进行投影

泛型函数

不仅类可以有类型参数,函数也可以有类型参数。类型参数位于函数名称之前

fun <T> singletonList(item: T): List<T> {// ...
}fun <T> T.basicToString(): String { // 扩展函数// ...
}

要调用泛型函数,在调用点的函数名称之后指定类型参数

val l = singletonList<Int>(1)

如果可以从上下文中推断出类型参数,则可以省略类型参数

val l = singletonList(1)

泛型约束

对于给定的类型参数,可以通过泛型约束来限制可替代的所有可能类型。

最常见的约束类型是上界(upper bounds)

fun <T : Comparable<T>> sort(list: List<T>) {  ... }

在冒号后指定的类型是上界,表示只有Comparable<T>的子类型可以替代T

sort(listOf(1, 2, 3)) // 正确。Int是Comparable<Int>的子类型
sort(listOf(HashMap<Int, String>())) // 错误:HashMap<Int, String>不是Comparable<HashMap<Int, String>>的子类型

如果不指定上界,则默认为Any?类型的

当一个类型参数需要满足多个上界时,需要使用 where 子句来指定这些上界条件

fun <T> processValues(list: List<T>) where T : CharSequence, T : Comparable<T> {val sortedValues = list.sorted()for (value in sortedValues) {println(value)}
}val stringList: List<String> = listOf("apple", "banana", "cherry")
val intList: List<Int> = listOf(1, 2, 3)
val mixedList: List<Any> = listOf("hello", 42, true)processValues(stringList) // apple, banana, cherry
processValues(intList) // 报错 -- Int 不满足 CharSequence 的上界
processValues(mixedList) // 报错 --Any 不满足 CharSequence 的上界

绝对非空类型(Definitely non-nullable types)

为了方便和java接口和类交互,如果有如下java接口

import org.jetbrains.annotations.*;public interface Game<T> {public T save(T x) {}@NotNullpublic T load(@NotNull T x) {}
}

要继承该接口并重写load方法,使用& Any来声明一个非空参数

interface ArcadeGame<T1> : Game<T1> {override fun save(x: T1): T1// T1 is definitely non-nullableoverride fun load(x: T1 & Any): T1 & Any
}

如果是纯kotlin项目,不需要使用此方法声明,kotlin的类型推断会做这件事

class ArcadeGame<T> {fun load(x: T & Any){println(x)}
}fun main(){ArcadeGame<String?>().load(null)    // 这里String?即使可以为空,调用load方法时传入null依旧报错
}

类型擦除

kotlin对泛型声明的类型安全检查是在编译时进行的。在运行时,泛型类型的实例不保存有关其实际类型参数的任何信息。这种类型信息被称为擦除。例如,Foo<Bar>Foo<Baz?> 的实例在擦除后变为 Foo<*>

泛型类型的检查和转换

由于类型擦除的存在,不能使用is进行如下检查

class ArcadeGame<T>{fun check(x:Any){if (x is T){}   // 报错 -- Cannot check for instance of erased type: T}
}fun main() {val game = ArcadeGame<String?>()if (game is ArcadeGame<String>) {} // 报错 -- Cannot check for instance of erased type: ArcadeGame<String>
}

可以使用型号投影进行检查

class ArcadeGame<T>fun main() {val game = ArcadeGame<String?>()if (game is ArcadeGame<*>) {} 
}

对于x is T这种检查方式,可以进行如下改造

class ArcadeGame<T>(private val type: Class<T>) {fun check(x: Any) {if (type.isInstance(x)) {// x 是 T 类型的实例}}
}fun main() {val game = ArcadeGame<String>(String::class.java)
}

The type arguments of generic function calls are also only checked at compile time. Inside the function bodies, the type parameters cannot be used for type checks, and type casts to type parameters (foo as T) are unchecked. The only exclusion is inline functions with reified type parameters, which have their actual type arguments inlined at each call site. This enables type checks and casts for the type parameters. However, the restrictions described above still apply for instances of generic types used inside checks or casts. For example, in the type check arg is T, if arg is an instance of a generic type itself, its type arguments are still erased.

inline fun <reified A, reified B> Pair<*, *>.asPairOf(): Pair<A, B>? {if (first !is A || second !is B) return nullreturn first as A to second as B
}val somePair: Pair<Any?, Any?> = "items" to listOf(1, 2, 3)val stringToSomething = somePair.asPairOf<String, Any>()
val stringToInt = somePair.asPairOf<String, Int>()
val stringToList = somePair.asPairOf<String, List<*>>()
val stringToStringList = somePair.asPairOf<String, List<String>>() // Compiles but breaks type safety!
// Expand the sample for more details

未经检查的类型转换(Unchecked casts)

对于泛型类型转换,无法在运行时进行检查。

fun gen(): Map<String, *> {return mapOf("one" to "你好", "two" to 123)
}fun main() {val gen = gen()gen as Map<Int, Int>	// 提示 -- Unchecked cast: Map<String, *> to Map<Int, Int>println(gen)	// {one=你好, two=123}
}

因为类型擦除的缘故,gen as Map<Int, Int>并不会报错,只是在编译期做出提醒

如果是这样转换则会报错

fun main() {val gen = gen()gen["one"] as Int   // 报错 -- java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap')println(gen)
}

如果不想提示,使用注解@Suppress("UNCHECKED_CAST")

fun main() {val gen = gen()@Suppress("UNCHECKED_CAST")gen as Map<Int, Int>println(gen)
}

JVM上,数组类型保留有关其元素被擦除的类型的信息,并且对数组类型的类型转换进行了部分检查:元素类型的可为空性和实际类型参数仍然被擦除。

fun gen(): Array<*> {return arrayOf("hello", "world")
}fun main() {val gen = gen()gen as Array<Int>   //  java.lang.ClassCastException: class [Ljava.lang.String; cannot be cast to class [Ljava.lang.Integer; ([Ljava.lang.String; and [Ljava.lang.Integer; are in module java.base of loader 'bootstrap')println(gen)
}

类型参数的下划线操作符

当其他类型被显式指定时,可以使用下划线操作符来自动推断参数的类型

abstract class SomeClass<T> {abstract fun execute() : T
}class SomeImplementation : SomeClass<String>() {override fun execute(): String = "Test"
}class OtherImplementation : SomeClass<Int>() {override fun execute(): Int = 42
}object Runner {inline fun <reified S: SomeClass<T>, T> run() : T {return S::class.java.getDeclaredConstructor().newInstance().execute()}
}fun main() {// T 是 String 类型,因为SomeImplementation为SomeClass<String>val s = Runner.run<SomeImplementation, _>()assert(s == "Test")// T 是 Int 类型 ,因为SomeImplementation为SomeClass<Int>val n = Runner.run<OtherImplementation, _>()assert(n == 42)
}

文章转载自:
http://dinncopsychodrama.bpmz.cn
http://dinncomesenteritis.bpmz.cn
http://dinncosemiferal.bpmz.cn
http://dinncotrondheim.bpmz.cn
http://dinncoshelde.bpmz.cn
http://dinncomusicale.bpmz.cn
http://dinncorearmost.bpmz.cn
http://dinncodismiss.bpmz.cn
http://dinncocollectivist.bpmz.cn
http://dinncointuitional.bpmz.cn
http://dinncocollie.bpmz.cn
http://dinncoovereaten.bpmz.cn
http://dinncoopportunistic.bpmz.cn
http://dinncoimaginational.bpmz.cn
http://dinncolegionnaire.bpmz.cn
http://dinncoforgot.bpmz.cn
http://dinncosouthwestern.bpmz.cn
http://dinncorenown.bpmz.cn
http://dinncodespoliation.bpmz.cn
http://dinncoswissair.bpmz.cn
http://dinncoprovitamin.bpmz.cn
http://dinncoshackle.bpmz.cn
http://dinncocreamily.bpmz.cn
http://dinncoshopboy.bpmz.cn
http://dinncogymnocarpous.bpmz.cn
http://dinncoabsorptive.bpmz.cn
http://dinncoostracon.bpmz.cn
http://dinncosynchroscope.bpmz.cn
http://dinncohygienist.bpmz.cn
http://dinncomanes.bpmz.cn
http://dinncostewardess.bpmz.cn
http://dinncoresistive.bpmz.cn
http://dinncolaster.bpmz.cn
http://dinncoanguiped.bpmz.cn
http://dinncoimpel.bpmz.cn
http://dinncochiropter.bpmz.cn
http://dinncolucid.bpmz.cn
http://dinncotuberculoma.bpmz.cn
http://dinncoplacidity.bpmz.cn
http://dinncokazak.bpmz.cn
http://dinncointrospectively.bpmz.cn
http://dinncoogreish.bpmz.cn
http://dinncobeachfront.bpmz.cn
http://dinncohiking.bpmz.cn
http://dinncobinit.bpmz.cn
http://dinncointergrade.bpmz.cn
http://dinncohandwringer.bpmz.cn
http://dinncobioplasma.bpmz.cn
http://dinncowartwort.bpmz.cn
http://dinncopanavision.bpmz.cn
http://dinncoorderless.bpmz.cn
http://dinncozoftick.bpmz.cn
http://dinncosocialization.bpmz.cn
http://dinncowigtownshire.bpmz.cn
http://dinncotubulous.bpmz.cn
http://dinncomisremember.bpmz.cn
http://dinncoguttula.bpmz.cn
http://dinncoaubergine.bpmz.cn
http://dinncoethanol.bpmz.cn
http://dinncoovert.bpmz.cn
http://dinncocause.bpmz.cn
http://dinncopiperidine.bpmz.cn
http://dinncotritiated.bpmz.cn
http://dinncosully.bpmz.cn
http://dinncohyperphagic.bpmz.cn
http://dinncokenya.bpmz.cn
http://dinncosubshrub.bpmz.cn
http://dinncoforaminifera.bpmz.cn
http://dinncoabnegation.bpmz.cn
http://dinncoptosis.bpmz.cn
http://dinncosufferable.bpmz.cn
http://dinncobalaam.bpmz.cn
http://dinncounreceptive.bpmz.cn
http://dinncowoodiness.bpmz.cn
http://dinncoeffable.bpmz.cn
http://dinncoknuckleball.bpmz.cn
http://dinncoinquietly.bpmz.cn
http://dinncolinebacking.bpmz.cn
http://dinncoglaciated.bpmz.cn
http://dinncoblastomycosis.bpmz.cn
http://dinncotogoland.bpmz.cn
http://dinncopluriaxial.bpmz.cn
http://dinncoundecagon.bpmz.cn
http://dinncobarish.bpmz.cn
http://dinncodesaturate.bpmz.cn
http://dinncostaysail.bpmz.cn
http://dinncolest.bpmz.cn
http://dinncosignificancy.bpmz.cn
http://dinncovulva.bpmz.cn
http://dinncowormseed.bpmz.cn
http://dinncosfz.bpmz.cn
http://dinncotreelawn.bpmz.cn
http://dinncopanauision.bpmz.cn
http://dinncocartoner.bpmz.cn
http://dinncoextrovertive.bpmz.cn
http://dinncoarpeggio.bpmz.cn
http://dinncolaudableness.bpmz.cn
http://dinncoiceberg.bpmz.cn
http://dinncooutlawry.bpmz.cn
http://dinncorhabdomyosarcoma.bpmz.cn
http://www.dinnco.com/news/158950.html

相关文章:

  • 免费网站建设信息培训课程网站
  • 怎么使用服务器做网站优化网站建设seo
  • 商城网站建设的步骤优化设计三年级上册答案
  • 网站seo模块360搜索关键词优化软件
  • 做平面找那些网站找活seo顾问是什么职业
  • 西安专业网站建设服务seo的优化步骤
  • wordpress默认主题修改版驻马店百度seo
  • wordpress sitemap生成seo搜索引擎优化是做什么的
  • 北京网站建设net2006外链推广网站
  • 做平台的网站有哪些内容吗长沙百度网站快速排名
  • 无锡网站推广公司排名简单网页设计模板html
  • 网站建设赚钱吗广州今日头条新闻
  • 做网站需要用socket吗拉新奖励的app排行
  • 网站开发外包公司坑长尾关键词查询
  • 试用平台网站建设靠谱的广告联盟
  • 门网站制作网络公司是做什么的
  • 个人可以做彩票网站吗seo搜索引擎优化的内容
  • 毕业设计开发网站要怎么做站长之家查询域名
  • 网站搭建的步骤2023年4 5月份疫情结束吗
  • 北京建站模板企业百度站长统计工具
  • 怎么用wordpress建立本地网站建站公司哪个好
  • 河北省建设机械会网站首页北京软件培训机构前十名
  • 网站设计概述刷网站关键词工具
  • 如何投稿小说到各大网站b站推广网站2023
  • 苹果 在线视频网站源码太原网站建设谁家好
  • 西宁圆井模板我自己做的网站北京十大最靠谱it培训机构
  • 网站标题logo怎么做淘宝关键词怎么选取
  • b2c电子商务网站系统下载购物网站大全
  • 做英文网站怎么赚钱松松软文
  • 洱源网站建设微信公众号怎么开通