Можно ли ссылаться на хранилище без копирования?

С например

struct Foo {
    mapping(address => uint) b;
}

Foo[] foo;

если функция имеет дело только с foo[4], может ли она ссылаться на него из хранилища, не копируя его? это что

function c() {
    Foo memory p = foo[4];
}

делает?

Ответы (1)

Чтобы получить ссылку из переменной в состоянии контракта, вы должны использовать storageквалификатор

function c() {
    Foo storage p = foo[4];
}

Внутри cфункции все изменения также pбудут обновляться .foo

ничего не копирует, верно? если я использую memory, копирует ли он что-нибудь или это ссылка, за исключением того, что ее нельзя обновить?
@cotld Если вы используете квалификатор памяти, он создаст копию структуры в памяти.
так что для EVM меньше работы storage? storageгаз тоже дешевле ?
@cotld Доступ к хранилищу стоит дороже, чтение uint из хранилища стоит 200 газа, из памяти — 3 газа, обновление uint из хранилища стоит 5000 или 20000 газа. Но память очень ограничена, если вы используете слишком много, стоимость быстро растет. На практике приходится пробовать разные подходы к снижению расхода газа, т.е. использовать только хранилище, только память или смешивать хранилище и память.