Kotlin扩展任何?.toString()
我一直在尝试在Kotlin中使用扩展函数。
class ExtensionExample() { var name: String? = null fun Any?.toString() : String { if (this == null) { return "Value is null" } return "Value is not null" } }
当我打印如下所示的名称variables
println(ExtensionExample().name.toString())
它应该打印像
Value is null
但它不像我预期的那样打印。 它只打印null
。
有人可以解释一下吗?
扩展函数有范围 。 这就是为什么它不能在ExtensionExample
类之外访问。
通常,扩展function被定义为顶层function。 也就是说,他们倾向于属于一个阶级之外 。
您的toString
扩展名在ExtensionExample
定义。 这是可能的 ,但这意味着它只能在这个类的范围内使用 ,而且只能在这个类中使用 。
你的main
方法可能是一个顶级函数(而不是该类的成员),所以它不能访问这个扩展函数。
只有其他成员可以访问这个扩展function:
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) { ExtensionExample().foo() }
打印"Value is null"
在线试用!
编译它的原因是被调用的toString
方法是kotlin-stdlib中的Any?.toString
方法。 也就是说, 这个方法已经存在了 。
fun Any?.toString(): String
返回对象的字符串表示forms。 可以用一个空的接收器来调用,在这种情况下,它返回字符串“null”。
将您的扩展function移出课程 。 你的扩展函数将会隐藏 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) { println(ExtensionExample().name.toString()) }
打印"Value is null"
,如你所愿。
在线试用!
请注意,您不能使用扩展function隐藏成员函数。 那是,
class Test { fun a() { println("a") } } fun Test.a() { println("b") } ... Test().a()
会导致打印出“a”。
为什么你的Any?.toString
工作(移出课后)的唯一原因是Any?
没有成员,因为它不是类,而是Any
类的可空types。 已经存在的toString
方法也是一个扩展,所以你的不被任何成员隐藏。
在类中定义一个扩展函数:
如果你想在ExtensionExample
保留toString()
的定义,你只能从那里使用它:
class ExtensionExample() { var name: String? = null // uses the toString() extension function defined in ExtensionExample fun useToString() = name.toString() fun Any?.toString(): String { if (this == null) { return "inside: Value is null" } return "inside: Value is not null" } }
这个
// uses the version of toString() defined in the Kotlin Standard library println(ExtensionExample().name.toString()) // uses the inside version of toString() println(ExtensionExample().useToString())
将打印
空值
里面:值是空的
在类之外定义一个扩展函数:
但如果你想在外面使用它,你必须把它移到外面:
class ExtensionExample() { var name: String? = null // uses the toString() extension function defined in ExtensionExample fun useToString() = name.toString() fun Any?.toString(): String { if (this == null) { return "inside: Value is null" } return "inside: Value is not null" } } fun Any?.toString(): String { if (this == null) { return "outside: Value is null" } return "outside: Value is not null" }
这个
// uses the outside version of toString() which overrides the one from the Kotlin Standard library println(ExtensionExample().name.toString()) // uses the inside version of toString() println(ExtensionExample().useToString())
将打印:
外部:值为空
里面:值是空的
如果一个类有一个成员函数,并且定义了一个具有相同接收器types,相同名称并适用于给定参数的扩展函数,则该成员总是获胜。
你的扩展方法不能影响Any
( Object
)类的内置toString
方法。
至于在可空types上调用toString
,这个方法已经在Kotlin运行时中了:
/** * Returns a string representation of the object. Can be called with a null receiver, in which case * it returns the string "null". */ public fun Any?.toString(): String
另请参阅有关扩展解决方案的文档 。