2016-03-16 65 views
1

我想将一些代码从C迁移到Rust以用于学习目的,并使我的学习库更加多语言化。如何在Rust中构造函数中创建数组

问题是我知道有一种方法可以将C库集成到Rust中。这样,我可能在Rust中使用calloc允许创建我的数组与运行时指定的范围。

但是我不想在这里使用calloc - 我想看看锈的方式。但我真的不想用vec!;之前我有一些愚蠢的问题,所以我现在不想使用它。

下面是代码:

pub struct Canvas { 
    width: usize, 
    height: usize, 
    array: [char], // I want to declare its type but not its size yet 
} 

impl Canvas{ 
    pub fn new (&self, width: usize, height: usize) -> Canvas { 
     Canvas { 
      width: width, 
      height: height, 
      array: calloc(width, height), // alternative to calloc ?   } 
    } 
} 

我希望我的问题仍然是惯用的以代码的方式锈。

回答

5

我想用坐标式的访问阵列

像这样的事情?

pub struct Canvas { 
    width: usize, 
    height: usize, 
    data: Vec<u8>, 
} 

impl Canvas { 
    pub fn new(width: usize, height: usize) -> Canvas { 
     Canvas { 
      width: width, 
      height: height, 
      data: vec![0; width*height], 
     } 
    } 

    fn coords_to_index(&self, x: usize, y: usize) -> Result<usize, &'static str> { 
     if x<self.width && y<self.height { 
      Ok(x+y*self.width) 
     } else { 
      Err("Coordinates are out of bounds") 
     } 
    } 

    pub fn get(&self, x: usize, y: usize) -> Result<u8, &'static str> { 
     self.coords_to_index(x, y).map(|index| self.data[index]) 
    } 

    pub fn set(&mut self, x: usize, y: usize, new_value: u8) -> Result<(), &'static str>{ 
     self.coords_to_index(x, y).map(|index| {self.data[index]=new_value;}) 
    } 
} 

fn main() { 
    let mut canvas = Canvas::new(100, 100); 
    println!("{:?}", canvas.get(50, 50)); // Ok(0) 
    println!("{:?}", canvas.get(101, 50)); // Err("Coordinates are out of bounds") 
    println!("{:?}", canvas.set(50, 50, 128)); // Ok(()) 
    println!("{:?}", canvas.set(101, 50, 128)); // Err("Coordinates are out of bounds") 
    println!("{:?}", canvas.get(50, 50)); // Ok(128) 
} 
+0

正是我在找的东西! – xetra11

+0

对于“内置”的感觉,请注意[Index](https://doc.rust-lang.org/std/ops/trait.Index.html)和[IndexMut](https:// doc.rust浪。org/std/ops/trait.IndexMut.html),可以实现'(usize,usize)'。他们不能报告错误,所以他们会补充你在这里写的方法,然后你可以使用'canvas [(50,50)] = 128'。 –

5

首先,我深深怀疑你不想char;我假设你想要一个“字节数组”,在这种情况下,你需要u8

其次,你不能真的这样使用[u8]。我不打算进入为什么因为这只会使答案脱轨。现在:如果你看到一个[T]不是后面有某种引用或指针,它的可能是的一个错误。

最后,这是Vec的用途;用它。你说你不想使用它,但不要指定原因。 Vec如何在Rust中分配动态大小的数组。如果你试图分配一个与C中完全相同的结构兼容的结构,那么这个问题就会发生很大的变化,你应该清楚这一点。

假设你想要的是“锈相当于”用C做的:

pub struct Canvas { 
    width: usize, 
    height: usize, 
    array: Vec<u8>, 
} 

impl Canvas { 
    pub fn new(width: usize, height: usize) -> Canvas { 
     Canvas { 
      width: width, 
      height: height, 
      array: vec![0; width*height], 
     } 
    } 
} 
+0

好吧然后我会用vec!宏。但我没有和他们一起过得很好。当我构造宽度为10,高度为10的画布时,“数组”的绑定将保持长度为100的vec(索引范围0-99)。在使用这个API之后,我想访问数组的第99个索引,我可以使用数组[99] - 到目前为止没有问题。但是当我想访问该数组与多维数组的坐标风格我不得不做数组[9] [9]这是不可能的,数组[9] [9]将导致数组[81]而不是9宽度和9的高度...多数民众赞成我遇到这个问题tbh – xetra11

+1

@ xetra11查看一个平面数组作为二维数组可以通过简单的算术(例如,按行主要顺序(x + y * width)它被称为我认为))。 –

+0

修复'pub fn new(&self,width:usize,height:usize)'到'pub fn new(width:usize,height:usize)' – qthree

相关问题