Kotlin扩展任何?.toString()

Zum*_*med 3 kotlin kotlin-android-extensions

我一直在尝试在Kotlin中使用扩展功能.

class ExtensionExample() {

   var name: String? = null

   fun Any?.toString() : String {

       if (this == null) {
           return "Value is null"
       }

       return "Value is not null"
   }
}
Run Code Online (Sandbox Code Playgroud)

当我打印名称变量如下所示

println(ExtensionExample().name.toString())
Run Code Online (Sandbox Code Playgroud)

它应该打印出来

Value is null
Run Code Online (Sandbox Code Playgroud)

但它不像我预期的那样打印.它只打印null.

有人可以解释一下吗?

Moi*_*ira 5

扩展函数具有范围.这就是为什么它不能在ExtensionExample课堂外访问.

通常,扩展函数被定义为顶级函数.也就是说,它们往往属于一个阶级之外.

您的toString扩展程序定义在ExtensionExample.这是可能的,但这意味着它仅在此类的范围内可用,并且仅适用于此类.

您的main方法可能是顶级函数(而不是该类的成员),因此它无权访问此扩展函数.

只有其他成员才能访问此扩展功能:

class ExtensionExample {

    var name: String? = null

    fun Any?.toString(): String {
        return if (this == null) "Value is null" else "Value is not null"
    }

    fun foo() {
        println(name.toString())
    }

}

fun main(args: Array<String>) {
    ExtensionExample().foo()
}
Run Code Online (Sandbox Code Playgroud)

版画 "Value is null"

在线尝试!

它编译的原因toString是被调用的Any?.toString方法是来自kotlin-stdlib的方法.也就是说,这种方法已经存在.

fun Any?.toString(): String

返回对象的字符串表示形式.可以使用null接收器调用,在这种情况下,它返回字符串"null".

将您的扩展功能移出课堂.然后,您的扩展函数将隐藏 stdlib的扩展名,并且未明确导入的同一包中的任何调用kotlin.toString都将使用您的函数.

这是您的代码的工作版本:

class ExtensionExample {

    var name: String? = null

}

fun Any?.toString(): String {
    return if (this == null) "Value is null" else "Value is not null"
}

fun main(args: Array<String>) {
    println(ExtensionExample().name.toString())
}
Run Code Online (Sandbox Code Playgroud)

打印"Value is null",如你所愿.

在线尝试!


请注意,您无法使用扩展功能隐藏成员函数.那是,

class Test {

    fun a() {
        println("a")
    }

}

fun Test.a() {
    println("b")
}

...
Test().a()
Run Code Online (Sandbox Code Playgroud)

将导致打印"a".

你的Any?.toString作品(在被移出课堂之后)的唯一原因是它Any?没有成员,因为它不是一个类,而是一个可以为类的可空类型Any.现有toString方法也是一个扩展,因此任何成员都不会隐藏您的方法.