CryptoZombies中getKitty函数为何选用storage而非memory?
getKitty中使用storage而非memory? 这个问题的核心其实是对Solidity中storage和memory在view函数中的行为理解有偏差——我们先拆解两者的差异,再看这个场景下的选择逻辑:
storage在这里是一个引用,而非拷贝
当你写Kitty storage kit = kitties[id];时,并没有把整个Kitty结构体从合约存储复制到某个地方,而是创建了一个指向kitties[id]存储位置的引用指针。这个操作的Gas成本极低,几乎可以忽略。后续访问kit.siringWithId、kit.cooldownEndBlock等字段时,是直接从合约存储中读取对应位置的单个字段值。memory会触发全结构体拷贝
如果改用Kitty memory kit = kitties[id];,Solidity会一次性把整个Kitty结构体的所有字段从合约存储加载到内存中,这一步需要支付读取所有字段的Gas成本。之后再从内存读取字段虽然便宜,但前期的全量加载反而可能比逐个读取字段的成本更高——尤其是当结构体字段较多时(比如这个Kitty有10个字段)。代码可读性与一致性
从代码风格来看,用storage引用更直观地表达了“我们直接访问存储中的数据”这个意图。CryptoZombies作为入门教程,也可能是为了强化开发者对storage引用用法的理解——毕竟在需要修改存储的函数中,storage引用是必不可少的,这里用同样的写法可以保持概念的连贯性。旧版本Solidity的编译器特性
考虑到CryptoZombies使用的是较旧的Solidity版本(比如0.4.x),当时的编译器对memory结构体拷贝的优化不如现在完善,使用storage引用在Gas成本上的优势会更明显。
总结一下:在这个view函数中,storage引用的Gas成本并不比memory高,反而可能更优;同时它还能更清晰地表达代码意图,和教程的教学目标契合,所以选择了storage而非memory。
内容的提问来源于stack exchange,提问作者Leo Sung

