kotlin - 来自不同类的调用扩展功能

标签 kotlin kotlin-extension

这个问题在这里已经有了答案:





How do I call extension methods from outside the class they are defined in?

(3 个回答)


3年前关闭。




我正在尝试创建一个非常简单的事务管理器,如下所示:

object PersistenceManager {
    private val dataSource: DataSource by lazy {
        val config = ConfigFactory.load()
        hikari(config.getConfig("postgres"))
    }

    private fun hikari(appConfig: Config): DataSource {
        // init datasource
    }

    fun <T> transaction(statement: Connection.() -> T): T {
        val connection = dataSource.connection
        try {
            return connection.statement()
        } catch (e: Exception) {
            connection.rollback()
            throw e
        } finally {
            connection?.close()
        }
    }
}

class BrandsDB {

    private val query = "select name from brands order by name"

    fun Connection.getAll(): List<String> {
        val ps = this.prepareStatement(query)
        val rs = ps.executeQuery()
        return JdbcMapperFactory.newInstance()
            .newMapper(String::class.java)!!.stream(rs).toList()
    }
}

class BrandsService(private val brandsDB: BrandsDB) {

    fun getBrands(): List<String> {
        return transaction {
            brandsDB.getAll() // I'd like to do something like this but since
                              // getAll() method belongs to Connecion, I can't
        }
    }
}

所以这一切背后的想法是我可以在一个 transaction 中进行多个查询。如果出现任何问题,我可以回滚的 block (我应该在这些查询中插入或更新)。我还想避免将连接传递给 brandsDB.getAll()方法,但让它以“隐式”方式获得连接。

我知道我可以提取 getAll()方法到它自己的文件或制作 BrandsDB类一个对象,但这可以在任何地方以静态方式调用该方法,这是我不喜欢的。我也不想将任何与数据库相关的代码放在 BrandsService 中。 ,只有业务逻辑应该去那里。

这可能吗?

最佳答案

Connection是 Java 中的接口(interface)(不是类!),因此您可以创建自己的接口(interface)来扩展它并委托(delegate)给它。


interface OurConnection : Connection {
   fun getAll() : SomeType
}

fun <T> PersistenceManager.extendedTransaction(action: OurConnection.() -> T) : T {
   //call the original method
   return PersistenceManager.transaction {
      object : OurConnection, Connection by this {
         override fun getAll() = TODO("implement me")
      }.action()
   }
}

我使用委托(delegate)实现,隐式委托(delegate) Connection我的界面中的方法。它是 Connection by this行,其中 this是来自 PersistenceManager.transaction 的 lambda 接收器对象函数调用。

关于kotlin - 来自不同类的调用扩展功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55415060/

相关文章:

lambda - Kotlin:内联 lambda 和重载解析歧义

Android Kotlin - 无法解析 Firebase

android - 为什么我的数据类给出空值,除非我对其应用默认值?

Kotlin 成员和扩展同时使用

arraylist - 如何制作和使用函数数组列表

android - Kotlin 的 EventBus 不工作

java - 如何使用 Firebase 从上传的文件中获取下载网址

kotlin - 使用 super 的 kotlin 中的扩展函数

android - Kotlin 扩展函数突然需要 api 级别 24

android - Kotlin Android 去抖动