【问题标题】:what does "::" mean in kotlin?"::" 在 kotlin 中是什么意思?
【发布时间】:2017-11-20 20:58:21
【问题描述】:

我是 Kotlin 的新手
我使用此代码打开另一个活动:

startActivity(Intent(this,IntroAndLang::class.java))

当前活动和目标活动是用 Kotlin 编写的

我不明白为什么IntroAndLang::class.java 上没有单个: 而不是::

【问题讨论】:

  • : 用于声明,:: 是运算符。见here
  • @m0skit0 谢谢,为什么当我使用 kotlin 类时它的 class.java?
  • Android API 只接受 Java 类,这就是为什么你需要传递一个 Java 类。 IntroAndLang::class 返回一个 KClass(一个 Kotlin 类),然后 .java 返回 Java 类。请注意,所有 Kotlin 类最终都会编译为 Java 类(.class 二进制文件)。

标签: android kotlin


【解决方案1】:

:: 将 Kotlin 函数转换为 lambda。

假设您有一个如下所示的函数:

fun printSquare(a: Int) = println(a * 2)

你有一个将 lambda 作为第二个参数的类:

class MyClass(var someOtherVar: Any, var printSquare: (Int) -> Unit) {
        
    fun doTheSquare(i: Int) {
        printSquare(i)
    }
}

如何将printSquare 函数传递给MyClass?如果您尝试以下方法,它将无法正常工作:

  MyClass("someObject", printSquare) //printSquare is not a LAMBDA, it's a function so it gives compile error of wrong argument

那么我们如何将 printSquare 转换为 lambda 以便我们可以传递它?使用:: 表示法。

MyClass("someObject",::printSquare) //now compiler does not complain since it's expecting a lambda and we have indeed converted the `printSquare` FUNCTION into a LAMBDA. 

另外,请注意this 是隐含的……意思是this::printSquare::printSquare 相同。因此,如果 printSquare 函数在另一个类中,例如 Presenter,那么您可以像这样将其转换为 lambda:

Presenter::printSquare

更新:

这也适用于构造函数。如果你想创建一个类的构造函数,然后将其转换为 lambda,它是这样完成的:

(x, y) -> MyClass::new

这在 Kotlin 中转换为 MyClass(x, y)

【讨论】:

  • 您确定MyObject::new 仍然有效吗?将其作为表达式包含在源代码中时出现错误。
  • 我不太同意这个答案的措辞,因为在编程语言的上下文中,“lambda”(通常)指的是 anonymous 函数。另一方面,:: 运算符(在此上下文中)创建了一个对函数的 可调用引用,即可用于稍后在代码中调用所述函数的名称。
【解决方案2】:

:: 用于 kotlin 中的反射

  1. 类参考val myClass = MyClass::class
  2. 函数参考this::isEmpty
  3. 属性参考::someVal.isInitialized
  4. 构造函数参考::MyClass

详细阅读Official Documentation

【讨论】:

  • 迄今为止最好的答案
  • @mohsen 同意。
  • 我想知道为什么 isInitialized 仅适用于 :: 运算符,但之后我找到了这个答案,现在我知道为什么了。 :: 运算符获取对该属性的引用。谢谢@Rahul Sharma
【解决方案3】:

正如docs 中所述,这是一个类参考

类参考: 最基本的反射特性是获取 Kotlin 类的运行时引用。要获取对静态已知 Kotlin 类的引用,可以使用类文字语法:

val c = MyClass::class
//The reference is a value of type KClass.

请注意,Kotlin 类引用与 Java 类引用不同。 要获取 Java 类引用,请在 KClass 实例上使用 .java 属性。

也是方法引用的语法,就像这个简单的例子一样:

list.forEach(::println)

它指的是在 Kotlin 标准库中定义的println

【讨论】:

  • ::printlnIntroAndLang::class 是不相关的,尽管它们都使用了 ::。方法引用无法评估为 KClass,它不是 SAM 类型!
  • 你说得对,这不是最干净的答案,我修改了它
  • :: 只是一种编写 lambda 表达式的方法,基本上我们可以使用它来引用方法,即成员函数或属性,例如 class Person (val name: String, val age: Int) 现在我们可以编写它来访问有最大年龄。 people.maxBy{it.age}我们可以把上面的修改成people.maxBy(Person::age)
【解决方案4】:

从 kotlin 1.1 开始,除了上面提到的类、函数、属性和构造函数引用之外,'::' 还可以用于获取对上述所有内容的绑定引用。

例如,使用 '::class' 可用于获取特定对象的确切类,尽管接收器的类型如下...

val widget: Widget = ...
assert(widget is GoodWidget) { "Bad widget: ${widget::class.qualifiedName}" }

widget::class 将对象“widget”的确切类返回为“GoodWidget”或“BadWidget”,尽管接收器表达式的类型(即最初声明的“Widget”)

更多信息https://kotlinlang.org/docs/reference/reflection.html

【讨论】:

    猜你喜欢
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2020-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多