У меня есть некоторый код, который, когда упрощен, выглядит следующим образом:Могу ли я создать «небезопасное закрытие»?
fn foo() -> Vec<u8> {
unsafe {
unsafe_iterator().map(|n| wrap_element(n)).collect()
}
}
Итератор возвращает элементы, которые будут признаны недействительными, если исходные данные изменились. К сожалению, я не могу полагаться на обычный механизм ржавчины mut
здесь (я делаю некоторые ... странные вещи).
Чтобы исправить небезопасность, я перемещаю итератор сразу и делаю копии каждого элемента (через wrap_element
), а затем бросаю все это в Vec
. Это работает, потому что ничто другое не имеет возможности войти и изменить базовые данные.
код работает как есть сейчас, но так как я использую эту идиому несколько раз, я хотел бы высыхают мой код немного:
fn zap<F>(f: F) -> Vec<u8>
where F: FnOnce() -> UnsafeIter
{
f().map(|n| wrap_element(n)).collect()
}
fn foo() -> Vec<u8> {
zap(|| unsafe { unsafe_iterator() }) // Unsafe block
}
Моя проблема с этим решением является то, что вызов unsafe_iterator
небезопасно, и это wrap_element
/collect
, что делает его безопасным снова. Способ структурирования кода не передает этого.
Я хотел бы как-то пометить свое закрытие как unsafe
, а затем вернуть ответственность за безопасность.
Создание нового набора признаков - интересная идея! Я полагаю, что сахарирование довольно привязано к компилятору и что я ничего не могу сделать, как конечный пользователь, чтобы украсть его для новых качеств? – Shepmaster
Возможно, вы сможете сделать что-то вроде одеяла, чтобы реализовать новые черты для старых черт, тогда вы получите неявное «преобразование» из синтаксиса закрытия в небезопасные черты. Я все равно не получу функциональный синтаксис вызова, но я думаю, что это прекрасный компромисс. – reem
[Я дал этот снимок] (http://is.gd/OgyWaO), но это не так полезно, как могло бы быть. Проблема в том, что компилятор все еще жалуется, когда мы «вызываем» небезопасное fn в закрытии, потому что он не знает, что «небезопасный» будет передан, поэтому нет шансов использовать сахар. – Shepmaster