为何向全局数组追加元素后仍需从函数返回该元素?
createItem()要返回Item实例? 这是个非常棒的问题,戳中了API设计里「职责清晰」和「调用友好」的关键点~咱们来聊聊这么做的几个核心原因:
直接高效,避免额外查找成本
如果你不返回实例,调用者要拿到刚创建的Item,就得去allItems数组里找——要么取最后一个元素,要么遍历匹配某个标识。但数组越大,遍历成本越高;而且取最后一个也不是绝对安全的(后面会说)。直接返回刚创建的实例,调用者能立刻拿到目标对象,一步到位。消除歧义,避免竞态问题
假设你的App是多线程的,或者在createItem()之后有其他代码也在往allItems里加元素,那调用者去数组里找「刚创建的那个」就可能拿到错误的对象。返回实例能彻底避免这种歧义,不管后续存储结构怎么变,拿到的都是刚创建的那个Item。API解耦,提升扩展性
ItemStore的职责是管理Item的存储,而createItem()的职责是「创建并存储一个Item」。返回实例的设计,让调用者不用关心ItemStore内部用什么来存Item——哪怕以后你把allItems从数组换成Set、Core Data或者其他存储方式,调用createItem()的代码完全不用改。如果调用者依赖从数组里查找,那存储结构一变,调用代码就得跟着改,这就是紧耦合的坑。支持链式调用,让代码更简洁
返回实例能让你写出更流畅的代码,比如创建Item后直接设置属性、传递给其他方法:let newItem = itemStore.createItem() newItem.title = "买牛奶" updateItemUI(newItem) // 甚至可以链式写: updateItemUI(itemStore.createItem().setTitle("买牛奶"))要是不返回实例,你就得先调用
createItem(),再去数组里找,代码会啰嗦很多。
举个反例,要是createItem()不返回实例,调用者的代码可能是这样:
itemStore.createItem() // 假设取最后一个,但这不一定是刚创建的! guard let newItem = itemStore.allItems.last else { // 还要处理空数组的情况 return } newItem.title = "买牛奶"
不仅麻烦,还存在潜在的错误风险。
内容的提问来源于stack exchange,提问作者Laurence Wingo

