Kotlin 扩展 Any?.toString()
Kotlin Extension Any?.toString()
我一直在尝试在 Kotlin 中使用扩展函数。
class ExtensionExample() {
var name: String? = null
fun Any?.toString() : String {
if (this == null) {
return "Value is null"
}
return "Value is not null"
}
}
当我像下面这样打印 name 变量时
println(ExtensionExample().name.toString())
它应该打印成
Value is null
但它没有像我预期的那样打印出来。它只打印 null
.
有人可以解释一下吗?
Extension functions have scopes。这就是为什么在 ExtensionExample
class.
之外无法访问它的原因
通常,扩展函数被定义为顶级函数。也就是说,它们往往属于 class.
之外
您的 toString
分机是在 ExtensionExample
中定义的。 This is possible,但是表示只在这个class的范围内可用,而这个class只。
您的 main
方法可能是顶级函数(而不是 class 的成员),因此它无法访问此扩展函数。
只有其他成员可以访问此扩展功能:
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()
}
打印"Value is null"
之所以编译通过,是因为调用的toString
方法是Any?.toString
method from the kotlin-stdlib。也就是说,这个方法已经存在。
fun Any?.toString(): String
Returns a string representation of the object. Can be called with a null receiver, in which case it returns the string "null".
将您的扩展函数移出 class。然后,您的扩展函数将 隐藏 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())
}
打印 "Value is null"
,如您所愿。
请注意,您不能使用扩展函数隐藏成员函数。也就是说,
class Test {
fun a() {
println("a")
}
}
fun Test.a() {
println("b")
}
...
Test().a()
将导致打印“a”。
您的 Any?.toString
工作的唯一原因(在移出 class 之后)是 Any?
没有成员 作为它不是 class,而是具有 class Any
的可空类型。已经存在的 toString
方法也是一个扩展,因此您的方法不会被任何成员隐藏。
If a class has a member function, and an extension function is defined which has the same receiver type, the same name and is applicable to given arguments, the member always wins.
您的扩展方法不能隐藏 Any
(Object
) class.
上的内置 toString
方法
至于在可空类型上调用 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
另见docs关于扩展的解析。
在 class:
中定义扩展函数
如果您想在 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())
将打印
null
inside: Value is null
在 class 之外定义扩展函数:
但是如果要在外面用,就得搬到外面去:
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())
将打印:
outside: Value is null
inside: Value is null
我一直在尝试在 Kotlin 中使用扩展函数。
class ExtensionExample() {
var name: String? = null
fun Any?.toString() : String {
if (this == null) {
return "Value is null"
}
return "Value is not null"
}
}
当我像下面这样打印 name 变量时
println(ExtensionExample().name.toString())
它应该打印成
Value is null
但它没有像我预期的那样打印出来。它只打印 null
.
有人可以解释一下吗?
Extension functions have scopes。这就是为什么在 ExtensionExample
class.
通常,扩展函数被定义为顶级函数。也就是说,它们往往属于 class.
之外您的 toString
分机是在 ExtensionExample
中定义的。 This is possible,但是表示只在这个class的范围内可用,而这个class只。
您的 main
方法可能是顶级函数(而不是 class 的成员),因此它无法访问此扩展函数。
只有其他成员可以访问此扩展功能:
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()
}
打印"Value is null"
之所以编译通过,是因为调用的toString
方法是Any?.toString
method from the kotlin-stdlib。也就是说,这个方法已经存在。
fun Any?.toString(): String
Returns a string representation of the object. Can be called with a null receiver, in which case it returns the string "null".
将您的扩展函数移出 class。然后,您的扩展函数将 隐藏 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())
}
打印 "Value is null"
,如您所愿。
请注意,您不能使用扩展函数隐藏成员函数。也就是说,
class Test {
fun a() {
println("a")
}
}
fun Test.a() {
println("b")
}
...
Test().a()
将导致打印“a”。
您的 Any?.toString
工作的唯一原因(在移出 class 之后)是 Any?
没有成员 作为它不是 class,而是具有 class Any
的可空类型。已经存在的 toString
方法也是一个扩展,因此您的方法不会被任何成员隐藏。
If a class has a member function, and an extension function is defined which has the same receiver type, the same name and is applicable to given arguments, the member always wins.
您的扩展方法不能隐藏 Any
(Object
) class.
toString
方法
至于在可空类型上调用 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
另见docs关于扩展的解析。
在 class:
中定义扩展函数如果您想在 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())
将打印
null
inside: Value is null
在 class 之外定义扩展函数:
但是如果要在外面用,就得搬到外面去:
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())
将打印:
outside: Value is null
inside: Value is null