标签: extension-function

可以以"静态"方式调用扩展函数吗?

是否可以创建一个扩展函数并将其称为静态

例如...

fun System.sayByeAndExit() {
    println("Goodbye!")
    System.exit()
}

fun main(args: Array<String>) {
    System.sayByeAndExit() // I'd like to be able to call this
}
Run Code Online (Sandbox Code Playgroud)

我知道代码示例不起作用......

  • 我理解kotlin的扩展函数是静态解析的,Kotlin Reference(扩展函数)中所述,但这并不意味着它们可以被调用,就好像它们是类中的静态函数(在Java意义上).

  • 我也明白这个代码不起作用,因为没有 System的实例传递给编译器将生成的方法; 因此它不会编译.

我为什么要这个?

有些人可能想知道为什么这种行为是可取的.我能理解为什么你会认为不是,所以这里有一些原因:

  1. 它具有标准扩展功能带来的所有好处.
  2. 不需要 仅为访问额外功能而创建类的实例.
  3. 可以从系统范围的上下文访问这些函数(前提是该类是可见的).

总结一下......

Kotlin有办法将静态函数"挂钩"到类中吗?我很想知道.

kotlin extension-function

5
推荐指数
1
解决办法
965
查看次数

Kotlin:如何调用super的扩展功能?

如何调用超级的扩展功能?

例如:

open class Parent {
    open fun String.print() = println(this)
}

class Child : Parent() {
    override fun String.print() {
        print("child says ")
        super.print() // syntax error on this
    }
}
Run Code Online (Sandbox Code Playgroud)

extension-methods kotlin extension-function

5
推荐指数
1
解决办法
339
查看次数

带回送功能的Kotlin扩展日志功能(slf4j)

我已经创建了用于记录日志的扩展功能:

import org.slf4j.LoggerFactory

fun Any.log(msg: String) {
    LoggerFactory.getLogger(javaClass.name).debug(msg)
}
Run Code Online (Sandbox Code Playgroud)

但是我不确定它是否会在任何时候被调用,因为方法LoggerFactory.getLogger调用getILoggerFactory

MB已经有人做过类似的事情,可以向我保证不会有任何内存泄漏:)吗?

现在我使用老式的方法(在类中声明logger字段):

companion object {
    private val logger = LoggerFactory.getLogger(LoggerTest::class.java.name)
}
Run Code Online (Sandbox Code Playgroud)

但是unit像这样的简单测试:

@Test
fun testLogger() {
    val start = System.currentTimeMillis()
    for (i in 0..999) {
        log("i=" + i)
    }
    val end = System.currentTimeMillis()
    val time = end - start
    println("*** TIME=" + time.toDouble() / 1000 + " sec")
}
Run Code Online (Sandbox Code Playgroud)

显示的结果与旧时尚选项相同:

@Test
fun testLogger() {
    val start = System.currentTimeMillis()
    for (i in 0..999) {
        logger.debug("i=" …
Run Code Online (Sandbox Code Playgroud)

logback slf4j kotlin extension-function

5
推荐指数
1
解决办法
1151
查看次数

理解lambda和接收器的困惑

科特林1.2.50

我一直在youtube https://www.youtube.com/watch?v=gPH9XnvpoXE上关注本教程的一些示例.有一些我已经理解的东西,但仍然存在一些混乱.我已将评论留在下面的代码中,我不知道发生了什么.

fun main(args: Array<String>) {

    val javaClient = createClient {
        firstName = "joe"
        lastName = "bloggs"

        twitter {
            handle = "@joebloggs"
        }
    }

    println(javaClient.toConsole)
}

/* Are we passing in a lambda and receiver. What will the receiver be */
private fun JavaClientBuilder.twitter(suppler: JavaTwitterBuilder.() -> Unit) {
    /* We call JavaTwitterBuilder().apply(..) Will apply return the newly created object? Not sure why we have to pass the suppler in the apply */
    twitter = JavaTwitterBuilder().apply(suppler).build()
}

/* Are …
Run Code Online (Sandbox Code Playgroud)

lambda kotlin extension-function

5
推荐指数
1
解决办法
198
查看次数

在 Kotlin 中仅向具有多个类型参数的扩展函数提供一个类型参数

介绍

在 Kotlin 中,我有一个通用转换扩展函数,它可以简化从一种this类型的对象C到另一种类型的对象T(声明为receiver)的转换,并提供额外的转换action,该转换视为receiver原始this对象并提供对原始对象的访问:

inline fun <C, T, R> C.convertTo(receiver: T, action: T.(C) -> R) = receiver.apply {
    action(this@convertTo)
}
Run Code Online (Sandbox Code Playgroud)

它的使用方式如下:

val source: Source = Source()
val result = source.convertTo(Result()) {
    resultValue = it.sourceValue
    // and so on...
}
Run Code Online (Sandbox Code Playgroud)

我注意到我经常在由无参数构造函数创建的函数上使用这个函数,并且认为通过创建基于其类型自动构建receivers的附加版本来进一步简化它会很好,如下所示:convertTo()receiver

inline fun <reified T, C, R> C.convertTo(action: T.(C) -> R) = with(T::class.constructors.first().call()) {
    convertTo(this, action) // calling the first version of convertTo() …
Run Code Online (Sandbox Code Playgroud)

generics default-constructor type-constraints kotlin extension-function

5
推荐指数
1
解决办法
1116
查看次数

Kotlin:伴生对象内的函数扩展

在 Kotlin 语言中,这个语法有什么作用以及如何工作?

class ClassName1 {
    companion object {          
        fun ClassName2.funName()=""         
    } 
}
Run Code Online (Sandbox Code Playgroud)

kotlin companion-object extension-function

5
推荐指数
1
解决办法
4774
查看次数

扩展功能内的Kotlin KClass实例

我需要访问通用扩展函数中的类类型。例如,如果我想做一个扩展函数以返回我正在扩展的类型的成员的集合,我会这样做:

fun <T> T.getMembers() =
       this::class.memberProperties
Run Code Online (Sandbox Code Playgroud)

问题是我不能在函数内部执行this :: class或T :: class。有什么方法可以访问泛型类型的类类型?

generics kotlin extension-function

3
推荐指数
1
解决办法
1525
查看次数

Kotlin在java.lang.reflect.Proxy对象上调用扩展函数时的奇怪行为

今天,我java.lang.reflect.Proxy在科特林(Kotlin)和一些人一起玩耍,对此行为感到惊讶:

import java.lang.reflect.Proxy

interface Dog {
  fun bark()
  fun bark3Times()
}

class DogImpl : Dog {
  override fun bark() = println("Bark!")
  override fun bark3Times() = repeat(3) { bark() }
}

fun Dog.bark5Times() = repeat(5) { bark() }

fun main(args: Array<String>) {

  val classLoader = Dog::class.java.classLoader

  val realDog: Dog = DogImpl()

  val proxyDog: Dog = Proxy.newProxyInstance(
    classLoader,
    arrayOf(Dog::class.java)
  ) { _, method, _ ->

    println("Proxy invoked! Method = ${method.name}")
    method.invoke(realDog)

  } as Dog

  println("--- Dog barking 3 times ---") …
Run Code Online (Sandbox Code Playgroud)

java reflection dynamic-proxy kotlin extension-function

3
推荐指数
1
解决办法
62
查看次数

如何在类上使用Kotlin扩展功能?

我有一个关于扩展功能的简短问题,该功能可以帮助清除一些代码。基本上,我对类名的hashCode进行了一些转换,并且我希望扩展函数执行这些转换。

例:

获得名称hashCode:StateA::class.java.name.hashCode()其中StateA是一个简单的类。

我想要扩展功能,如:

    fun Class<*>.transformName(): String {
       var hashString = this.javaClass.name.hashCode()

       //Do my stuff on that hashString

       return hashString
    }
Run Code Online (Sandbox Code Playgroud)

但这似乎不起作用。当我使用扩展功能时StateA.transformName(),该功能给我未解析的引用带来了错误。

我尝试了各种操作,例如将函数应用于StateA::class或使hashString等于,this::class.java.name.hashCode()但无济于事。有小费吗?

android class function kotlin extension-function

3
推荐指数
1
解决办法
57
查看次数

Kotlin:扩展函数的惯用用法 - 将扩展函数放在它扩展的类旁边

我看到 Kotlin 中扩展函数的一些用法我个人认为这没有意义,但似乎有一些指导方针“显然”支持它(解释问题)。

具体来说:在类之外(但在同一个文件中)定义一个扩展函数:

data class AddressDTO(val state: State,
                      val zipCode: String,
                      val city: String,
                      val streetAddress: String
)

fun AddressDTO.asXyzFormat() = "${streetAddress}\n${city}\n${state.name} $zipCode"

Run Code Online (Sandbox Code Playgroud)

其中asXyzFormat()被广泛使用,并且不能被定义为专用/内部(也为情况下,可能)。

在我的常识中,如果您拥有代码 ( AddressDTO) 并且用法不是某个类/模块的本地(因此是私有/内部) - 没有理由定义扩展函数 - 只需将其定义为成员函数班级。

  • 边缘情况:如果你想避免从get-开始的函数序列化- 注释类以获得所需的行为(例如@JsonIgnore在函数上)。这个恕我直言仍然不能证明扩展功能是合理的。

我对此的反驳是,官方 Kotlin 编码约定支持这种方式的扩展功能。具体来说:

自由地使用扩展函数。每次你有一个主要作用于一个对象的函数时,考虑使它成为一个接受该对象作为接收者的扩展函数。 来源

和:

特别是,当为与该类的所有客户端相关的类定义扩展函数时,请将它们放在定义类本身的同一文件中。在定义仅对特定客户端有意义的扩展函数时,将它们放在该客户端的代码旁边。不要创建文件只是为了保存“Foo 的所有扩展名”。 来源

我将感谢任何普遍接受的来源/参考解释为什么将函数移动为类的成员和/或实用参数支持这种分离更有意义。

kotlin extension-function

3
推荐指数
2
解决办法
219
查看次数