为什么需要代码B在输入参数中使用SQLiteDatabase。()?

代码A很好,为了简​​单起见,有人写了代码B.

我不明白为什么在代码B中的参数应该是(transactionFun:SQLiteDatabase.()->Unit)

我认为CodeF中的(transactionFun: ()->Unit)也不错,对不对?

代码A

 fun excuteTransaction(transactionFun:()->Unit){ val db = dbHelper.writableDatabase try{ db.beginTransaction() transactionFun() db.setTransactionSuccessful() }finally { db.endTransaction() } } 

代码B

 fun SQLiteDatabase.executeTransaction(transactionFun:SQLiteDatabase.()->Unit){ try{ beginTransaction() transactionFun() setTransactionSuccessful() }finally { endTransaction() } } 

代码A是好的,但要访问您的dbHelper您应该声明一个变量并将其发送到lambda。 代码B更好,因为你可以访问没有变量的dbHelper ,因为它是扩展函数。 我认为这看起来更好。 例如,调用代码A看起来像

 fun callCodeA() { excuteTransaction { dbHelper.execSQL("sone query") } } 

调用代码B看起来像

 fun callCodeB() { dbHelper.executeTransaction { execSQL("sone query") } } 

关于SQLiteDatabase.() -> Unit 。 它需要避免变量并获得访问权限。 在lambda里面,你不能访问当前的对象实例。 最简单的方法是将当前对象发送给lambda。 例如,你可以做

 fun SQLiteDatabase.executeTransaction(transactionFun: (SQLiteDatabase) -> Unit){ try{ beginTransaction() transactionFun(this) setTransactionSuccessful() }finally { endTransaction() } } 

但通过使用lambda扩展函数,它看起来更好。