扩展 Kotlin 的扩展

Extending Kotlin's extension

我正在尝试为 KLogger/Logger 创建一个扩展,它是 slf4j 记录器的扩展,以便更好地处理结构化日志消息。有人可以解释我的代码有什么问题以及如何在不传递我的记录器对象的情况下修复它或解决它吗?我的分机从未被调用。

下面您可能会看到简约的 build.gradle + 代码片段:

App.kt:

import mu.KLogger
import mu.KotlinLogging

private val log = KotlinLogging.logger {}

fun main() {
    log.info("log message",
            "key1" to "value1",
            "key2" to "value2"
    )
}

fun KLogger.info(message: String, vararg keyValues: Pair<String, Any?>) {
    log.info("log extension")
    info(message)
}

build.gradle.kts:

plugins {
    kotlin("jvm") version "1.3.72"
}

group = "rg"
version = "1.0"
java.sourceCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("ch.qos.logback:logback-classic:1.2.3")
    implementation("io.github.microutils:kotlin-logging:1.7.6")
}

更新: 我最终放弃了扩展想法并将现有代码转换为委托。

fun structuredLogger(func: () -> Unit): StructuredLogger = StructuredLogger(func)

class StructuredLogger(func: () -> Unit, private val log: KLogger = KotlinLogging.logger(func)) : KLogger by log {

    fun info(msg: String?, vararg keyValues: Pair<LoggingKey, Any?>) {
        log.info(marker(*keyValues), msg)
    }

    // (...)
}

Logger 具有签名为 info(message: String, vararg arguments: Any) 的函数(转换为 Kotlin)。虽然你的 vararg 用于 Pairs,但这只是 Any 的模棱两可的重载。扩展函数不能覆盖非扩展函数,如果覆盖的话将被简单地忽略。您将不得不更改函数名称或参数。