Kotlin的扩展功能是一种将行为添加到无法控制的类型(JDK或第三方库)的好方法。
例如,JDK的String
类提供toLowerCase()
和toUpperCase()
方法,但没有提供大写的字符串。 在Kotlin中,可以通过扩展功能将所需的行为添加到String
类来帮助您:
funString.capitalize()=when{
length<2->toUpperCase()
else->Character.toUpperCase(toCharArray()[0])+substring(1).toLowerCase()
}
println("hello".capitalize())
但是,扩展功能的使用不限于外部类型。 它还可以改善自己的代码库,以更优雅地处理空值。
这是在Kotlin中定义类和函数的一种方式:
classFoo{
funfoo()=println("foo")
}
然后,可以分别在不可空和可空类型上使用它,如下所示:
valfoo1=Foo()
valfoo2:Foo?=Foo()
foo1.foo()
foo2?.foo()
注意,编译器强制使用null-safe ?.
可空类型实例上的运算符,以防止NullPointerException
。
与其直接在类型上定义foo()
方法,不如将它定义为扩展函数,但要有所不同。 让我们做?.
函数定义的运算符部分:
classFoo
funFoo?.safeFoo()=println("null-safe foo")
现在,用法有了一些修改:
valfoo1=Foo()
valfoo2:Foo?=Foo()
valfoo3:Foo?=null
foo1.safeFoo()
foo2.safeFoo()
foo3.safeFoo()
无论类型是否为不可为空,调用语法都是一致的。 有趣的是,输出如下:
null-safe foo null-safe foo null-safe foo
是的,可以在null
实例上调用方法! 现在,让我们稍微更新Foo
类:
classFoo{
valfoo=1
}
如果foo()
扩展函数应该打印foo
属性而不是常量字符串怎么办?
funFoo?.safeFoo()=println(foo)
编译器抱怨:
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Foo?
扩展功能需要根据编译器的错误进行修改:
funFoo?.safeFoo()=println(this?.foo)
输出变为:
1 1 null
扩展功能是使API更加一致并优雅地处理null
的好方法,而不是减轻调用者代码的负担。
翻译自: https://blog.frankel.ch/extension-functions-for-more-consistent-apis/