我试图通过构建非常简单的方法和扩展内置类的属性getter来学习更多关于Kotlin抽象类扩展和泛型的知识。我大部分都很成功,但我被Number类难倒了。我的测试属性Number.sgn
旨在返回符号(1或-1作为Int)。为了简单起见,负数应该返回-1,而正数和0应该返回1。我对这个方法的用例不是特别感兴趣,我的模块中唯一的导入是kotlin.text.*
,我收到的错误消息确实提到了那里的一个冲突。我只是不明白为什么它会冲突,以及如何克服它--尽管我猜这是一个新手错误。
我首先编写了代码来扩展Int类,它工作得很好:inline val Int.sgn get() = if (this<0) -1 else 1 // sign of number
然后,我尝试将其泛化并移动到Number类,如下所示:inline val Number.sgn get() = if (this<0) -1 else 1 // doesn't compile
编译错误如下:unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public fun String.compareTo(other: String, ignoreCase: Boolean = ...): Int defined in kotlin.text inline fun Number.sgn() = if (this<0) -1 else 1 ^
然后我尝试了一种不同的方法,使用泛型:inline val <T:Number> T.sgn get() = if (this<0) -1 else 1
我从编译器收到了同样的错误:error: unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public fun String.compareTo(other: String, ignoreCase: Boolean = ...): Int defined in kotlin.text inline val <T:Number> T.sgn get() = if (this<0) -1 else 1 ^
谁能帮助我理解为什么有类型不匹配,为什么kotlin.text
在这里很重要?有没有一种方法,我可以用来克服这个问题,并让这个属性getter应用到Number的所有子类?(再次,我知道这不是一个有意义的用例,而是一个简化的例子,以帮助我理解这背后的原则。)提前感谢任何人可以给予的任何建议。
2条答案
按热度按时间cbeh67ev1#
你的第一个函数可以工作,因为
Int
实现了Comparable<Int>
,这就是<
运算符被转换成的内容。但是,如果你看一下Number
类,你会发现它只有转换到它的各种子类的函数-它没有实现Comparable
,因此,你不能在它上面使用<
运算符。你可以做的是先将
Number
转换为Double
,然后看看它是否为负:您还可以通过将
Number
的compareTo
函数实现为扩展来使原始代码(带或不带泛型)工作:请注意,将所有内容强制转换为
Double
可能会导致精度损失。sr4lhrrt2#
你甚至可以用相同类型的结果来做。
内存中的更多优化-将源编号转换为字节: