rust笔记五

http://doc.rust-lang.org/guide.html#crates-and-modules
15 crates和modules

一个木箱是一个独立的编译单元,可以包含一个module hierarchy,最顶层的module叫crate root,,比如建一个新工程:

$ cd ~/projects
$ cargo new modules --bin
$ cd modules
生成的src/main.rs就是一个crate,在其中可以定义很多module
fn main() {
    println!("Hello, world!")
}

mod hello {
    fn print_hello() {
        println!("Hello, world!")
    }
}
可以把mod关键字想像成java中的class,这样就好理解了,其中的方法默认都是private的,加上pub关键字就成了public
fn main() {
    hello::print_hello();
}

mod hello {
    pub fn print_hello() {
        println!("Hello, world!")
    }
}
16测试
测试代码可以写在任何地方
#[test]
fn is_one_equal_to_one() {
    assert_eq!(1i, 1i);
}

和java比,,,@Test变成了#[test],要多出2个蛋疼的符号,为嘛不用@Test

16.1Attributes
#[test]这玩意在rust中叫Attributes,在java中叫Annotation, Attr可以标记在任何的rust item上,比如:

  • functions
  • modules
  • type definitions
  • structures
  • enumerations
  • static items
  • traits
  • implementations
这些和let一样都不是表达式, 形式有3种
#[test], #[cfg=test],#[cfg(unix,target_word_size="32")],他们作用在紧跟其后的方法上

16.2继续Attributes

如果是#后加个!,  hash bang?我在写shell吗?
#!表示作用在整个crate上(初学,我暂时理解为当前所在的文件)
6种级别deprecated,experimental,unstable,stable,frozen,locked
warn就是专门为这些级别而生的一种Attributes,用法如下:

// applies to the crate we're in
#![warn(unstable)]

extern crate some_crate;

// applies to the following `fn`.
#[test]
fn a_test() {
  // ...
}
warn(unstable)表示如果导入了标记为unstable的模块,就要报警了~如果不加warn标记,默认只有deprecated会报警

16.3写测试代码
$ cd ~/projects
$ cargo new testing --bin
$ cd testing
在源码中写的test叫unit test,在tests目录下写的test叫integration test.
vi tests/lib.rs
#[test]
fn foo() {
    assert!(true);
}
此时cargo test一下,测试成功,但是会报警main()方法未被使用,这样就行
#[cfg(not(test))]
fn main() {
    println!("Hello, world!")
} 
我稍微玩了一个#!,,,she bang!!!看看我的src/main.rs
#![cfg(not(test))]
fn main() {
    println!("Hello, world!");
    bar();
}
fn bar(){}

#![cfg(not(test))]表示在测试的时候编译我,但不要报警??(这点没完全明白, 报不报警有那么重要..)

来个完整的:
首先是在src/lib.rs中定义一个新的方法, 然后是分别在src/main.rs和tests/lib.rs中使用这个方法
src/lib.rs代码如下:

pub fn add_three_times_four(x: int) -> int {
    times_four(add_three(x))
}

fn add_three(x: int) -> int { x + 3 }

fn times_four(x: int) -> int { x * 4 }
src/main.rs中这样使用
extern crate testing;

#[cfg(not(test))]
fn main() {
    println!("Hello, world!")
}
tests/lib.rs中这样测试
extern crate testing;
use testing::add_three_times_four;

#[test]
fn math_checks_out() {
    let result = add_three_times_four(5i);

    assert_eq!(32i, result);
}

使用extern crate导入crate,使用use导入方法 ...我想std是默认已经导入的crate,而testing需要我们手动导入..不明白为什么还要多一个导入crate的动作..java中为嘛一个import就能搞定

其中src/lib.rs中的两个私有方法,不能做tests测试(容我这样叫),只能做unit测试,修改src/lib.rs如下:

pub fn add_three_times_four(x: int) -> int {
    times_four(add_three(x))
}

fn add_three(x: int) -> int { x + 3 }

fn times_four(x: int) -> int { x * 4 }

#[cfg(test)]
mod test {
    use super::add_three;
    use super::times_four;

    #[test]
    fn test_add_three() {
        let result = add_three(5i);

        assert_eq!(8i, result);
    }

    #[test]
    fn test_times_four() {
        let result = times_four(5i);

        assert_eq!(20i, result);
    }
}  
可以看到把测试的方法组织到了一个mod下面,个人认为纯属好看,
比较蛋疼的是在mod中不能直接使用crate中定义的方法?????还需要显示的use super::,太丑了.
另外#[cfg(test)]有什么用,我去掉后,,提示这两个use super::是多余的import,,,但其实这两个方法即使不在mod上加#[cfg(test)]还是会走测试.只能认为这里的设计还有待改进.

看下面这段,,这两个方法测试通过,,但系统会把use是多余的,但是去掉use又提示找不到要测试的方法
pub fn add_3_times_4(x: int) -> int {
  times_4(add_3(x))
}
fn times_4(x:int) -> int {
    x*4
}
fn add_3(x:int)->int{
    x+3
}
mod test{
    use super::add_3;
    use super::times_4;
    #[test]
    fn test_add_3(){
        let result = add_3(5i);
        assert_eq!(8i, result);
    }
    #[test]
    fn test_times_4(){
        let result = times_4(5i);
        assert_eq!(20i, result);
    }
}

cyper@zerorun:~/rust/projects/testing$ cargo test
   Compiling testing v0.0.1 (file:///home/cyper/rust/projects/testing)
/home/cyper/rust/projects/testing/src/lib.rs:11:9: 11:21 warning: unused import, #[warn(unused_imports)] on by default
/home/cyper/rust/projects/testing/src/lib.rs:11     use super::add_3;
                                                        ^~~~~~~~~~~~
/home/cyper/rust/projects/testing/src/lib.rs:12:9: 12:23 warning: unused import, #[warn(unused_imports)] on by default
/home/cyper/rust/projects/testing/src/lib.rs:12     use super::times_4;
                                                        ^~~~~~~~~~~~~~
     Running target/lib-20cb46c181088f0d

running 1 test
test math_checks_out ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

     Running target/testing-4b195e8c06dad98e

running 2 tests
test test::test_add_3 ... ok
test test::test_times_4 ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured

     Running target/testing-c693f606fb5b87e0

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests testing

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

cyper@zerorun:~/rust/projects/testing$
不过再次运行cargo test上面的报警会消失..运行cargo clean后再次运行cargo run或cargo test报警又会出现.

总之,,下面这两个到底有什么用没弄明白!
#![cfg(not(test))]
#![cfg(test)]

end!









你可能感兴趣的:(rust笔记五)