什么时候应该选择Kotlin扩展函数?
在Kotlin中,至少有一个参数的函数可以定义为常规的非成员函数,也可以定义为一个参数为接收者的函数 至于作用域,似乎没有什么区别:两者都可以在类和其他函数的内部或外部声明,并且都可以或不可以具有相同的可见性修饰符 语言参考似乎不建议在不同的情况下使用常规函数或扩展函数 所以,我的问题是:什么时候扩展函数比常规的非成员函数更有优势?什么时候常规函数比扩展函数更有优势什么时候应该选择Kotlin扩展函数?,kotlin,code-structure,Kotlin,Code Structure,在Kotlin中,至少有一个参数的函数可以定义为常规的非成员函数,也可以定义为一个参数为接收者的函数 至于作用域,似乎没有什么区别:两者都可以在类和其他函数的内部或外部声明,并且都可以或不可以具有相同的可见性修饰符 语言参考似乎不建议在不同的情况下使用常规函数或扩展函数 所以,我的问题是:什么时候扩展函数比常规的非成员函数更有优势?什么时候常规函数比扩展函数更有优势 foo.bar(baz,baq)vsbar(foo,baz,baq) 这仅仅是函数语义的一个暗示(接收者绝对是焦点),还是在使用扩
foo.bar(baz,baq)
vsbar(foo,baz,baq)
这仅仅是函数语义的一个暗示(接收者绝对是焦点),还是在使用扩展函数时会使代码更干净或打开机会?至少有一种情况是扩展函数是必须调用的链接,也称为“流畅风格”: 假设您希望使用自己的操作从Java8扩展流接口。当然,您可以使用普通函数来实现这一点,但它看起来非常丑陋:
doZ(doY(doX(someStream())))
显然,您希望为此使用扩展函数。
此外,不能将普通函数设为中缀,但可以使用扩展函数:
infix fun <A, B, C> ((A) -> B).`|`(f: (B) -> C): (A) -> C = { a -> f(this(a)) }
@Test
fun pipe() {
val mul2 = { x: Int -> x * 2 }
val add1 = { x: Int -> x + 1 }
assertEquals("7", (mul2 `|` add1 `|` Any::toString)(3))
}
infixfun((A)->B)。```(f:(B)->C:(A)->C={A->f(this(A))}
@试验
风笛{
val mul2={x:Int->x*2}
val add1={x:Int->x+1}
assertEquals(“7”,(mul2``add1``Any::toString)(3))
}
扩展功能与安全呼叫操作员配合得非常好。。如果您希望函数的参数有时为null
,而不是提前返回,请将其设置为扩展函数的接收者
普通功能:
fun nullableSubstring(s: String?, from: Int, to: Int): String? {
if (s == null) {
return null
}
return s.substring(from, to)
}
fun String.extensionSubstring(from: Int, to: Int) = substring(from, to)
扩展功能:
fun nullableSubstring(s: String?, from: Int, to: Int): String? {
if (s == null) {
return null
}
return s.substring(from, to)
}
fun String.extensionSubstring(from: Int, to: Int) = substring(from, to)
呼叫地点:
fun main(args: Array<String>) {
val s: String? = null
val maybeSubstring = nullableSubstring(s, 0, 1)
val alsoMaybeSubstring = s?.extensionSubstring(0, 1)
fun main(args:Array){
val s:字符串?=null
val-maybeSubstring=nullableSubstring(s,0,1)
val alsoMaybeSubstring=s?.extensionSubstring(0,1)
正如您所看到的,两者都做相同的事情,但是扩展函数较短,并且在调用站点上,很明显结果是可以为空的。扩展函数在某些情况下很有用,在其他情况下是必需的: 惯用格:
ObjectMapper
类添加方法,从而简化TypeReference
和泛型的处理null
上调用的新方法或现有方法添加null安全性。例如String?的String的扩展函数。isNullOrBlank()
允许您在null
字符串上使用该函数,而无需先执行自己的null
检查。函数本身在调用内部函数之前进行检查。请参阅final
,这在接口中当前是不允许的)。这在需要内联具体化函数时非常有用支持时,当前不支持该用法。您可以添加一个iterator()
扩展方法,该方法遵循中描述的规则--即使返回的类似迭代器的对象也可以使用扩展来满足提供next()的规则
和hasNext()
+
和*
(1的专门化,但不能以任何其他方式进行,因此是必需的)。请参阅Path
类,很难找到文件。exist(Path)
方法,因为它的名称间隔很奇怪。该函数可以直接放在路径。exists()上。(@kirill)
在某些情况下,您必须使用扩展方法。例如,如果您有一些列表实现
MyList
,您可以编写一个扩展方法,如