- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
Kotlin 如何消除函数调用、构造函数、伴生对象和调用重载的歧义?在 Kotlin 1.3.11
中,我可以在同一个作用域内声明两个同名成员:
fun main(args: Array<String>) {
val test = object {
operator fun invoke() = println("test invocation")
}
test() // Prints: "test invocation"
// I think this should fail to compile, but it works
fun test() = println("test function")
test() // Prints: "test function"
}
您可能认为它使用的是最新的声明,但事实并非如此!
fun main(args: Array<String>) {
fun test() = println("test function")
val test = object {
operator fun invoke() = println("test invocation")
}
test() // Prints: "test function"
}
但也有一些奇怪的作用域交互。如果我将函数声明移到外面:
fun test() = println("test function")
fun main(args: Array<String>) {
val test = object {
operator fun invoke() = println("test invocation")
}
test() // Prints "test invocation"
}
同样,如果我将对象移到外面,这也会编译:
val test = object {
operator fun invoke() = println("test invocation")
}
fun main(args: Array<String>) {
fun test() = println("test function")
test() // Prints: "test function"
}
我也可以把它们都移到外面:
val test = object {
operator fun invoke() = println("test invocation")
}
fun test() = println("test function")
fun main(args: Array<String>) {
test() // Prints: "test function"
}
但是如果我使用类名重载 test
,它不会编译:
class test {} // Does not compile
fun test() = println("test function")
val test = object {
operator fun invoke() = println("test invocation")
}
尝试编译此程序会导致以下错误:
Error:(1, 6) Conflicting overloads: public fun test(): Unit defined in root package in file Simplest version.kt, public constructor test() defined in test, public val test: Any defined in root package in file Simplest version.kt, public final class test defined in root package in file Simplest version.kt
Error:(1, 6) Conflicting declarations: public fun test(): Unit, public constructor test(), public val test: Any, public final class test
Error:(2, 0) Conflicting overloads: public fun test(): Unit defined in root package in file Simplest version.kt, public constructor test() defined in test, public val test: Any defined in root package in file Simplest version.kt, public final class test defined in root package in file Simplest version.kt
Error:(3, 4) Conflicting declarations: public fun test(): Unit, public constructor test(), public val test: Any, public final class test
但是在使用嵌套作用域时它确实可以编译:
class test {
constructor() {
println("test constructor")
}
}
fun main(args: Array<String>) {
fun test() = println("test function")
val test = object {
operator fun invoke() = println("test invocation")
}
test() // Prints: "test function"
}
伴随对象和构造函数之间也存在一些歧义:
class test {
constructor() {
println("test constructor")
}
companion object {
operator fun invoke() = println("test companion invocation")
}
}
fun main(args: Array<String>) {
test() // Prints: "test constructor"
}
不知何故,下面的例子也可以编译:
class test {
constructor() {
println("test constructor")
}
companion object {
operator fun invoke() = println("test companion invocation")
}
}
fun main(args: Array<String>) {
test() // Prints: "test constructor"
val test = object {
operator fun invoke() = println("test invocation")
}
test() // Prints: "test invocation"
fun test() = println("test function")
test() // Prints: "test function"
}
这更不直观:
class test {
constructor() {
println("test constructor")
}
companion object {
operator fun invoke() = println("test companion invocation")
}
operator fun invoke() = println("test invocation overload")
}
fun main(args: Array<String>) {
val test = test() // Prints: "test constructor"
val test1 = test() // Prints: "test invocation overload"
}
重载命名成员的规则是什么?为什么 Kotlin 编译器会接受同一作用域内的可调用变量和同名函数,但不接受同名类的存在(在某些情况下,但在其他情况下不接受)?此外,在存在具有相同调用站点语法的作用域构造函数或伴随对象的情况下,调用如何工作?
最佳答案
根据我在 kotlin-spec.asc#order-of-evaluation 中看到的内容有三个规则在起作用(不幸的是,有些地方的文字不完整):
A simple name is a single identifier. Its meaning depends on what symbol with that name are in scope. If only on symbols with that name is in scope, then the simple name refers to it. If there are multiple symbols with this name are in scope, then, informally, the symbol whose declaration is "closest" to the occurrence of the simple name is selected. For more precise rules, see TODO
如果所有同名符号都在同一级别,则函数优先于带有调用的属性
实际顺序是
- function descriptor (
fun foo()
in the containing class)- dispatch receiver (see declaring-extensions-as-members)
In case of a name conflict between the members of the dispatch receiver and the extension receiver, the extension receiver takes precedence.
- 扩展接收器(
fun A.foo() 在类之外定义
)- Task Prioritizer(据我了解,根据类型找到最佳匹配,或者例如当有一些默认参数时。我认为这是
invoke
所属的类别)
如果你把它应用到你的最后一个例子中:
class test {
constructor() {
println("test constructor")
}
companion object {
operator fun invoke() = println("test companion invocation")
}
operator fun invoke() = println("test invocation overload")
}
fun main(args: Array<String>) {
val test = test() // Prints: "test constructor" //you create a local variable with invoke. Constructor is executed.
val test1 = test() // Prints: "test invocation overload" //invoke of the local variable is called.
test.Companion() //access the companions' invoke which is shadowed by the other invoke.
}
关于kotlin - Kotlin 如何调度调用运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54045644/
我正在查看Kotlin Github page我注意到 Kotlin 语言本身大部分是用 Kotlin 编写的:我只是想知道,一种语言怎么可能大部分都是用它自己的语言编写的?在您可以使用正在创建的语言
我有以下非常简单的 kotlin 代码来演示中缀函数 com.lopushen.demo.presentation 包 fun main(args: Array) { print("Hello
我在 Java 中有 2 个模型类,其中一个扩展了另一个 @UseStag public class GenericMessages extends NavigationLocalizationMap
Kotlin 代码 runBlocking { flow { for (i in 0..4) { println("Emit $i")
这三个 Kotlin 插件和它们的实际作用有什么区别? plugins { id 'kotlin-android' id 'org.jetbrains.kotlin.android'
我正在为某些现有库添加 Kotlin 原生 linuxX64 目标支持。库已成功编译,但在运行测试用例时,出现以下运行时错误: kotlin.native.concurrent.InvalidMuta
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 2 年前。 Improve t
我创建了一个类并向其添加了一个与成员函数具有相同签名的扩展,并执行了这个方法,它总是执行成员方法。 class Worker { fun work() = "...working" } fun
我知道传递给函数的参数将被视为“val”,即使变量被初始化为“var”。但这对我来说一直是个问题。在下面的示例代码中,我想通过使用函数“changeNum”修改变量“num”的值。但当然,Kotlin
现在,我正在尝试用 Kotlin 重写我的 Java 应用程序。然后,我遇到了日志语句,比如 log.info("do the print thing for {}", arg); 所以我有两种方法可
有点出名article关于许多语言的异步编程模型的状态,指出它们存在“颜色”问题,特别是将生态系统分为两个独立的世界:异步和非异步。以下是这种语言的属性: 每个函数都有一种颜色,红色或蓝色(例如asy
因为 KDoc 文档生成引擎是 abandoned in favor of Dokka , Kotlin 文档应该称为“KDoc 注释”,还是“Dokka 注释”? 最佳答案 如所述here , KD
我想在可空对象上传递函数引用。以 Android 为例,假设我想使用 Activity#onBackPressed来自作为该事件的子级的片段。 如果我想调用这个函数,我可以很容易地做到 activit
我有一个列表 (x, y)其中y只能是 0 或 1 这样 例如: [(3, 0), (3, 1), (5, 1)] [(5, 0), (3, 1), (5, 1)] [(1, 1), (3, 1),
从强类型语言的定义来看: A strongly-typed programming language is one in which each type of data (such as intege
这不能编译的事实是否意味着它们不是一流的类型? fun foo(s: String): Int = s.length // This won't compile. val bar = foo 有没有办
如果在 Java i++是一个表达式和 i++;是一个表达式语句,分号(;) 在 Kotlin 中是可选的,是 i++ Kotlin 中的表达式或表达式语句? 最佳答案 i++是一个表达式,因为它有一
代码(如下所示)是否正确?它取自 Kotlin-docs.pdf 的第 63 页,这也是 https://kotlinlang.org/docs/reference/generics.html 的最后
我正在尝试使用 Kotlin 为 Android 的一些全局 API 解析器(检查网络连接、调用 API 并通过来自源的单个调用返回格式化数据),并且在某些时候我不得不创建一个通用类型 object就
kotlinlang 中的任务: 使用月份变量重写此模式,使其与格式 13 JUN 1992(两位数字、一个空格、一个月份缩写、一个空格、四位数字)中的日期相匹配。 答案是:val month = "
我是一名优秀的程序员,十分优秀!