Nim: Адреса параметров и изменчивости
Я пытаюсь определиться с политикой Нима, стоящей заexpression has no address
, В частности, у меня есть функция C, которая берет указатель (+ длина и т. Д.) Некоторого буфера данных. Я знаю, что эта функция будетне изменить данные. Упрощенная:
type
Buffer = object
data: seq[float]
proc wrapperForCCall(buf: Buffer) =
# accessing either buf.addr nor buf.data.addr produces
# Error: expression has no address
# workaround:
var tmp = buf.data # costly copy
callToC(tmp.len, tmp.addr) # now it works
С одной стороны, это имеет смысл, так как параметр, кажется, ведет себя точно так же, какlet
привязка, которая также "не имеет адреса". С другой стороны, я озадачен этим утверждением в руководстве:
Параметры var никогда не нужны для эффективной передачи параметров.
Насколько я вижу, единственный способ избежать копирования данных - это либо:
передавая параметр какbuf: var Buffer
передавая ссылку, т.е. используяref object
.В обоих случаях это говорит о том, что моя функция изменяет данные. Кроме того, он вводит изменчивость на сайт вызывающей стороны (т.е. пользователи больше не могут использовать привязки let для своих буферов). Ключевой вопрос для меня: «Я знаю», чтоcallToC
только для чтения, могу ли я убедить Нима разрешить обе неизменности без копии? Я вижу, что это опасно, так как я должен точно знать, что вызов неизменен. Таким образом, для этого потребуется какой-то механизм «небезопасного адреса», позволяющий принудительно указывать на неизменяемые данные?
И моя последняя загадка адресов параметров: я попытался сделать копию явной, изменив тип наBuffer {.bycopy.} = object
, В этом случае копирование уже происходит во время вызова, и я ожидаю, что теперь у меня будет доступ к адресу. Почему в этом случае доступ запрещен?