Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to use rust structs from other mods

Tags:

rust

Simple rust question that I can't seem to find an answer to:

I have defined a structure in a separate file. When I want to use this strut at the top of the file do something like:

use other_file::StructName;
mod other_file;

When I create a function that uses this type

fn test(other : StructName) {};

I get a warning about using a private type. This error is fixed when I write:

fn test(other : other_file::StructName) {};

This requires a lot of extra typing though. I can also reexport the module with pub use but I would really like to keep it hidden.

How do I correctly include modules to save typing? The python equivalent to what I want is

from other_file import StructName

===== Edit/ Example Code =======

The above code does not seem to reproduce or describe the problem I am having. The following for sure does in 2 files. It is a stripped down version of some matrix math utils.

geometry.rs

use geometry::{Vec3};
mod geometry;

#[deriving(Eq, Clone, Show)]
pub struct Mat4 {
  data : ~[f32]
}

impl Mat4 {

  fn apply_Vec3(&self, other : &Vec3) -> Vec3{
    let x = self.data[0] * other.x + self.data[1] * other.y + self.data[2] * other.z;
    let y = self.data[4] * other.x + self.data[5] * other.y + self.data[6] * other.z;
    let z = self.data[8] * other.x + self.data[9] * other.y + self.data[10]* other.z;
    Vec3::new(x, y, z)
  }
}

#[deriving(Eq, Clone, Show)]
pub struct Transform {
  mat : Mat4
}

impl Transform {
  pub fn apply_Vec3(&self, vec : &Vec3) -> Vec3 {
    self.mat.apply_Vec3(vec)
  }
}

transform.rs

#[deriving(Eq, Clone, Show)]
pub struct Vec3 {
  x : f32,
  y : f32,
  z : f32
}
impl Vec3 {
  pub fn new(x : f32, y : f32, z : f32) -> Vec3 {
    Vec3{x : x, y : y, z : z}
  }
}

When compiling with rustc --test transform.rs I get two errors:

transform.rs:25:39: 25:43 warning: private type in exported type signature, #[warn(visible_private_types)] on by default
transform.rs:25       pub fn apply_Vec3(&self, vec : &Vec3) -> Vec3 {
                                                      ^~~~
transform.rs:25:48: 25:52 warning: private type in exported type signature, #[warn(visible_private_types)] on by default
transform.rs:25       pub fn apply_Vec3(&self, vec : &Vec3) -> Vec3 {
                                                               ^~~~
like image 889
luke Avatar asked Mar 18 '14 21:03

luke


2 Answers

I'm assuming that you're actually returning an other_file::StructName; you wouldn't get that warning otherwise.

The problem is that from somewhere else, you can't actually access the type for other_file::StructName. As you are accessing it, I presume that StructName is public, but that's not enough for things outside this module to access it: the module other_file needs to be public as well.

Replace

mod other_file;

with

pub mod other_file;

Your use statement is correct and does indeed correspond to the Python from x import y statement. (Approximately only; it's an absolute path unless self or super come into it—those that would be .foo or ..foo in Python.)

like image 148
Chris Morgan Avatar answered Oct 10 '22 11:10

Chris Morgan


In Rust, everything is private by default (with only few exceptions, see this in the docs). So, the problem is perhaps that your struct StructName is private to the other_file module.

If you declare the struct as public in e.g. b.rs:

pub struct StructName {x: int, y: int}

You can successfully use it in e.g. a.rs as you wrote:

use b::StructName;
mod b;
fn test (s: StructName) -> int {return s.x + s.y;}
fn main () {
    let s = StructName {x: 1, y: 2};
    let t = test (s);
    println! ("{:i}", t);
}

This successfully compiles with Rust 0.9 and outputs 3.

like image 43
Gassa Avatar answered Oct 10 '22 12:10

Gassa