Rustデータ構造

4381 ワード

notice
Rust    1.0,    ,      

Structs
Rust構造体は、struct Name { field1: T1, field2: T2 [, ...] }の形式で宣言することができる.T 1,T 2はタイプを表し、1つのstructをインスタンス化しても同様の構文を使用し、Point { x: 1.0, y: 2.0 }のようなstructキーワードはありません.Rustの構造体はCと非常に類似しており,メモリレイアウトも同様であるため,CプログラムからRustのstructを読み取ることができる.mypoint.xの形式でstructの値にアクセスします.
struct Point {
    x: f64,
    y: f64
}

structのインスタンスが可変である場合、このインスタンスのフィールドも可変です.たとえば
let mut mypoint = Point { x: 1.0, y: 1.0 }; //   
let origin = Point { x: 0.0, y: 0.0 }; //    

mypoint.y += 1.0; // `mypoint`      ,    
origin.y += 1.0; // ERROR: assigning to immutable field
matchモードマッチングもstructにマッチングできます.基本的な構文はName { fieldname: pattern, ... }です.
match mypoint {
    Point { x: 0.0, y: yy } => println!("{}", yy),
    Point { x: xx,  y: yy } => println!("{} {}", xx, yy)
}

structのパターンマッチングでは、すべてのフィールドを必要としない場合があります...(Name { field1, .. })を使用して、他のフィールドを無視できます.たとえば、次のようにします.
match mypoint {
    Point { x, .. } => println!("{}", x)
}

Enums列挙
簡単な列挙タイプ定義:
enum Direction {
    North,
    East,
    South,
    West
}

このうちNorthは0,Eastは1,Southは2,and Westは3である.既定値は、前の値に1を加算します.asを使用してNorthをintに変換できます
println!( "{:?} => {}", North, North as int );

定数値を指定します.
enum Color {
  Red = 0xff0000,
  Green = 0x00ff00,
  Blue = 0x0000ff
}

より複雑な状況:
enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point)
}
Circleは1つのPoint構造体を含み、1つのf 64Rectangleは2つのPoint構造体を含む.宣言は、タイプShapeShapeが、タイプを構築するために2つの関数ShapeおよびCircleを加えた1つの・Rectangleタイプの値を指すことを定義する.Circle(Point { x: 0.0, y: 0.0 }, 10.0)と書くように新しいCircleを作成し、もちろんモードマッチングも可能であり、列挙インスタンス値にアクセスする唯一の方法は解構である.例:
use std::f64;
fn area(sh: Shape) -> f64 {
    match sh {
        Circle(_, size) => f64::consts::PI * size * size,
        Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y)
    }
}
_を使用して個々のフィールドを無視し、すべてのフィールドを無視してCircle(..)を使用します.列挙されたパターンマッチング:
fn point_from_direction(dir: Direction) -> Point {
    match dir {
        North => Point { x:  0.0, y:  1.0 },
        East  => Point { x:  1.0, y:  0.0 },
        South => Point { x:  0.0, y: -1.0 },
        West  => Point { x: -1.0, y:  0.0 }
    }
}

列挙変数はstructであってもよい.例えば、
use std::f64;
enum Shape {
    Circle { center: Point, radius: f64 },
    Rectangle { top_left: Point, bottom_right: Point }
}
fn area(sh: Shape) -> f64 {
    match sh {
        Circle { radius: radius, .. } => f64::consts::PI * square(radius),
        Rectangle { top_left: top_left, bottom_right: bottom_right } => {
            (bottom_right.x - top_left.x) * (top_left.y - bottom_right.y)
        }
    }
}

Tuplesタプル
タプル(Tuples)はstructに似ていますが、タプルのフィールドには名前がありません.ポイントからフィールドにアクセスすることもできません.タプルには任意の要素があり、0の要素がない場合(()が好きなら、空のタプルとして使用できます).
let mytup: (int, int, f64) = (10, 20, 30.0);
match mytup {
  (a, b, c) => info!("{}", a + b + (c as int))
}

Tuple structs
Rustはtuple structs,メタセットと構造体の結合を提供した.tuple structsは名前付き(Foo(1,2)のタイプがBar(1,2)とは異なる)です.tuple structsのフィールドには名前がありません.
例:
struct MyTup(int, int, f64);
let mytup: MyTup = MyTup(10, 20, 30.0);
match mytup {
  MyTup(a, b, c) => info!("{}", a + b + (c as int))
}

1つのフィールドのみのtuple structsは、newtypes(Haskellの「newtype」プロパティのような)と呼ばれます.タイプの別名ではなく、新しいタイプを作成するために使用されます.
struct GizmoId(int);

このようなタイプ定義は、ベースタイプを区別するのと同じですが、用途の異なるデータは役に立ちます.
struct Inches(int);
struct Centimeters(int);

上記の定義は、異なるセルの数字を混同することを簡単に回避することができる.整数値はパターンで一致します.
let length_with_unit = Inches(10);
let Inches(integer_length) = length_with_unit;
println!("length is {} inches", integer_length);