在代码中,lambda 的类型不匹配,它是如何工作的?

In the code, the type of the lambda is mismatched, how does it work?

我在 Android 上使用 Epoxy library

我很好奇的是为什么 lambda expressionparameter 在类型不匹配时不会报错。

listener 是一个 lambda expression,它以 Int type 作为参数。

但是listener(addDetailClicked)工作正常。

不应该是listener(Int)吗?或 listener({ i -> addDetailClicked(i) }).

其实写了代码我也不知道为什么会这样

这怎么可能?

型号

@EpoxyModelClass(layout = R.layout.item_routine)
abstract class EpoxyRoutineModel() : EpoxyModelWithHolder<EpoxyRoutineModel.Holder>() {
    @EpoxyAttribute
    var workout: String = "see"

    @EpoxyAttribute
    var curPos: Int = 0

    @EpoxyAttribute
    lateinit var listener: (Int) -> Unit // this

    override fun bind(holder: Holder) {
        holder.workout.text = workout
        holder.add_btn.setOnClickListener {
            listener(curPos)
        }
    }
}

控制器

class RoutineItemController(
    private val addDetailClicked: (Int) -> Unit)
    : EpoxyController() {
    private var routineItem : List<RoutineItem>? = emptyList()

    override fun buildModels() {
        var i:Int =0
        routineItem?.forEach {
            when(it) {
               is RoutineItem.RoutineModel ->
                   EpoxyRoutineModel_()
                       .id(i++)
                       .curPos(i++)
                       .workout("d")
                       .listener(addDetailClicked) // why? listener(Int) or listener({ i -> addDetailClicked(i) })
                       .addTo(this)
           }

        }
    }
}

片段

class WriteRoutineFragment : Fragment() {
    private var _binding : FragmentWriteRoutineBinding? = null
    private val binding get() = _binding!!
    private lateinit var epoxyController : RoutineItemController
    private val vm : WriteRoutineViewModel by viewModels { WriteRoutineViewModelFactory() }

    override fun onCreateView(inflater: LayoutInflater,
                              container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        _binding = FragmentWriteRoutineBinding.inflate(inflater, container, false)

        epoxyController = RoutineItemController(::addDetail)
        binding.rv.adapter = epoxyController.adapter
        binding.rv.itemAnimator = null

        return binding.root

    }
    private fun addDetail(pos: Int) {
        vm.addDetail2(pos)
    }
}

我相信您错过了 EpoxyRoutineModel_ 包含 EpoxyRoutineModel 中的数据类型的设置器这一事实。例如,EpoxyRoutineModel.curPosInt 类型,所以 EpoxyRoutineModel_.curPos() 是一个声明为:

的函数
fun curPos(Int): EpoxyRoutineModel_

(或类似)

同样,EpoxyRoutineModel.listener(Int) -> Unit类型,所以EpoxyRoutineModel_.listener()声明为:

fun listener((Int) -> Unit): EpoxyRoutineModel_

所以listener()是一个接收另一个函数的函数(它自己接收Int)。所以我们可以在那里提供addDetailClicked