在代码中,lambda 的类型不匹配,它是如何工作的?
In the code, the type of the lambda is mismatched, how does it work?
我在 Android
上使用 Epoxy library
。
我很好奇的是为什么 lambda expression
的 parameter
在类型不匹配时不会报错。
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.curPos
是 Int
类型,所以 EpoxyRoutineModel_.curPos()
是一个声明为:
的函数
fun curPos(Int): EpoxyRoutineModel_
(或类似)
同样,EpoxyRoutineModel.listener
是(Int) -> Unit
类型,所以EpoxyRoutineModel_.listener()
声明为:
fun listener((Int) -> Unit): EpoxyRoutineModel_
所以listener()
是一个接收另一个函数的函数(它自己接收Int
)。所以我们可以在那里提供addDetailClicked
。
我在 Android
上使用 Epoxy library
。
我很好奇的是为什么 lambda expression
的 parameter
在类型不匹配时不会报错。
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.curPos
是 Int
类型,所以 EpoxyRoutineModel_.curPos()
是一个声明为:
fun curPos(Int): EpoxyRoutineModel_
(或类似)
同样,EpoxyRoutineModel.listener
是(Int) -> Unit
类型,所以EpoxyRoutineModel_.listener()
声明为:
fun listener((Int) -> Unit): EpoxyRoutineModel_
所以listener()
是一个接收另一个函数的函数(它自己接收Int
)。所以我们可以在那里提供addDetailClicked
。