如何在使用命名参数接收项目集合时不暴露对象的数据结构?
用命名参数替代vararg流畅接口构建Cart对象
你想通过命名参数实现和原vararg流畅接口类似的简洁对象构建方式,但你给出的代码存在类型不匹配的问题——withItems = { Item(), Item() }是一个无参Lambda,返回值是最后一个Item实例,类型为() -> Item,而Cart构造函数需要的是Collection<Item>类型,所以这段代码无法编译通过。
下面给出几种可行的实现方式,帮你用命名参数达到类似原写法的效果:
方案1:直接传递集合实例
最直接的方式是用listOf创建Item集合后,通过命名参数传递给Cart构造函数:
class Cart(val withItems: Collection<Item>) class Item fun main() { Cart( withItems = listOf(Item(), Item(), Item()) ) }
方案2:给构造函数添加vararg参数
如果想保留原写法中直接传递多个Item的便捷性,可以让Cart的构造函数支持vararg参数,内部自动转换为集合,这样既可以用命名参数,又能直接传多个元素:
class Cart(vararg initialItems: Item) { val withItems: Collection<Item> = initialItems.toList() } class Item fun main() { // 用命名参数传递时,需要将数组展开 Cart( initialItems = *arrayOf(Item(), Item(), Item()) ) // 如果不需要严格用命名参数,也可以直接传多个元素,写法更简洁 // Cart(Item(), Item(), Item()) }
方案3:定义辅助函数简化集合创建
如果觉得每次写listOf麻烦,可以定义一个顶层辅助函数来简化集合的创建,让调用写法更贴近原流畅接口:
// 辅助函数:将多个Item转为集合 fun items(vararg items: Item) = items.toList() class Cart(val withItems: Collection<Item>) class Item fun main() { Cart( withItems = items(Item(), Item(), Item()) ) }
以上三种方案都能实现你想要的“用命名参数构建带多个Item的Cart”的需求,其中方案2和3更贴近原写法的简洁性。
内容的提问来源于stack exchange,提问作者ibrahim koz
相关产品推荐
相关产品推荐

