2016-08-22 2 views
3
struct Device; 

struct CommandBuffer { 
    device: &Device, 
    // ... 
} 

// Does not work because Rust does not allow internal pointers 
struct Something { 
    device: Device, 
    command_buffer: CommandBuffer, 
} 

Одним из решений было бы использовать ArcВозможно ли иметь внутренние указатели без использования `Arc`?

struct CommandBuffer { 
    device: Arc<Device>, 
    // ... 
} 
struct Something { 
    device: Arc<Device>, 
    command_buffer: CommandBuffer, 
} 

Недостатком из Arc является косвенностью, атомный счетчиком, а также возможность избежать объема и сохраняя Device живо.

Теперь я не думаю, что вы можете работать с одним уровнем косвенности в Rust, но можно ли создать что-то между Box и Arc?

struct CommandBuffer { 
    device: BoxRef<Device>, 
    // ... 
} 
struct Something { 
    device: Box<Device>, 
    command_buffer: CommandBuffer, 
} 

Основная проблема, которую я имел при попытке реализовать BoxRef было то, что мне нужно, чтобы иметь возможность перемещать Box, даже если в настоящее время занимает в ней. Это должно быть технически безопасным из-за уровня косвенности, но я не думаю, что это может быть в настоящее время выражено в Rust.

let boxed_device = Box::new(device); 
let device_ref = boxed_device.boxed_ref(); 

// Owner of the reference should be allowed to move 
Something{device: boxed_device, CommandBuffer{device: device_ref}} 
  1. Может BoxRef быть реализованы? Я быстро просмотрел owning_ref , но он, похоже, не решает проблему, которая у меня есть.

  2. Какие еще варианты я могу выразить «внутренние указатели» в Rust?

+0

Возможно, я ошибаюсь, но похоже, что вы после «RefCell», возможно? –

+0

@SimonWhitehead «RefCell» также нельзя перемещать, когда есть активные роли, или я неправильно понимаю ваш вопрос? –

+0

Извинения, я думаю, что неправильно понял ваш - было поздно ночью. Без использования 'unsafe' .. насколько я знаю,' Arc' и/или 'Rc' с пользовательской оболочкой будет единственным способом сделать это. –

ответ

1

Это будет работать:

struct Device; 

struct CommandBuffer<'a> { 
    device: &'a Device, // ... 
} 

struct Something<'a> { 
    device: &'a Device, 
    command_buffer: CommandBuffer<'a>, 
} 

fn main() { 

    let dev = Device; 

    let smth = Something { 
     device: &dev, 
     command_buffer: CommandBuffer { device: &dev }, 
    }; 
} 

Вы не должны беспокоиться о Arcпроизводительности, что много.

возможности избежать объема может быть легко расправилась с помощью просто написав NewType, который держит Arc частные, и реализует только Deref к &T без Clone.

Смежные вопросы