取类型大小(字节)

int.sizeof
(char*).sizeof
double.sizeof
Foo.sizeof

//Rust
size_of::<i32>()
size_of::<*const i8>()
size_of::<f64>()
size_of::<Foo>()
let a = 10i32;
println!("{}", size_of_val(&a));

​秀​​​中​​空构​​​占​​0​​字节.

取类型最大值和最小值

在D中,使用​​类型属性​​:

char.max
char.min
ulong.max
double.min_normal
//Rust 使用类 C 常量:
i8::MAX
i8::MIN
u64::MAX
f64::MIN

特殊浮点值

double.nan
double.infinity
double.dig
double.epsilon
double.mant_dig
double.max_10_exp
double.max_exp
double.min_10_exp
double.min_exp

f64::NAN
f64::INFINITY
f64::DIGITS
f64::EPSILON
f64::MANTISSA_DIGITS
f64::MAX_10_EXP
f64::MAX_EXP
f64::MIN_10_EXP
f64::MIN_EXP

断定

assert( e == 0 );

//
assert!(condition);
assert_eq!(a, b);

​秀​​​中为宏,​​D​​​中发布版禁用​​断定​​​.​​assert(0)​​为禁止访问区.

遍历数组(集合)

int array[17];
foreach( value ; array ) {
func( value );
}

let array = [0; 17];
for value in &array {
println!("{}", value);
}

初化数组:

int array[17];
array[] = value;
//
let array = [value; 17];

变长数组:

int[] array;
int x;
array.length = array.length + 1;
array[ array.length - 1 ] = x;
//
let mut array = Vec::new();
array.push(value);

连接串

char[] s1;
char[] s2;
char[] s;

s = s1 ~ s2;
s ~= "hello";

//
let s1 = "abc";
let s2 = "eee";
let mut s = s1.to_owned() + s2;
s.push_str("world");

​秀​​​无显式转换​​类型​​​,未实现​​+=​​.

格式化输出

import std.stdio;

writefln( "调用%s次数!" , ntimes );
//
println!("Calling all cars {} times!" , ntimes);

前向声明

都用模块,不必前向声明.

fn foo() -> Test {
bar()
}

fn bar() -> Test {
Test { a: 10, b: 20 }
}

struct Test {
a: i32,
b: i32,
}

无参函数

void foo() {
...
}

fn foo() {
...
}

退出多个代码块

Louter: for( i = 0 ; i < 10 ; i++ ) {
for( j = 0 ; j < 10 ; j++ ) {
if (j == 3) break Louter;
if (j == 4) continue Louter;
}
}

'outer: for i in 0..10 {
'inner: for j in 0..10 {
if i == 3 {
break 'outer;
}
if j == 4 {
continue 'inner;
}
}
}

结构命名空间

同样,两种语言都无单独的​​结构命名空间​

分支串

void dostring( string s ) {
switch( s ) {
case "hello": ...
case "goodbye": ...
case "maybe": ...
default: ...
}
}

fn do_string(s: &str) {
match s {
"hello" => {},
"goodbye" => {},
"maybe" => {},
_ => {},
}
}

​秀​​​有成熟的​​模式匹配​​.

enum Type {
Common,
Secret,
Unknown,
}

struct Data {
id: i32,
data_type: Type,
info: Vec<i32>,
}

fn check_data(data: &Data) {
match *data {
Data { id: 42, .. } => println!("无尽问题..."),
Data { data_type: Type::Secret, info: ref i, .. } if i.is_empty() => println!("空的"),
_ => println!("数据"),
}
}

对齐字段

struct ABC {
int z; // z默认对齐

align(1) int x; // x字节对齐
align(4) {
... // {}中双字对齐
}
align(2): // 从此,字对齐

int y; // y字对齐
}

在​​Rust​​​中,只能完全​​禁用单个结构​​对齐:

#[repr(packed)]
struct Abc {
...
}

匿名构和联

D支持​​匿名结构​​​,允许为​​嵌套实体​​​保留​​扁平​​​的​​外部接口​​:

struct Foo {
int i;
union {
struct { int x; long y; }
char* p;
}
}

Foo f;

f.i;
f.x;
f.y;
f.p;

​Rust​​无匿名结构或联合,类似代码如下:

enum Bar {
Baz {x: i32, y: i32 },
Option(i8),
}

struct Foo {
i: i32,
e: Bar,
}

此外,​​Rust​​​禁止意外​​引用​​​已初化的​​错误联合字段​​.因此,必须区别对待他们:

match f.e {
Bar::Val(a) => println!("{}", a),
Bar::Baz { x, y } => println!("{} and {}", x, y),
}

因此,​​联合​​​不能用作​​(半)合法​​类型转换,但可消除潜在错误.

定义构和变量

两种语言都需要​​单独​​​声明​​类型和变量​​,不能像C这样:

struct Foo { int x; int y; } foo;

取构字段偏移

在D中,字段有个特殊的​​offsetof​​属性:

struct Foo { int x; int y; }
off = Foo.y.offsetof;

​秀​​无.但以后可能会添加.

union U { int a; long b; }
U x = { a : 5 };

​Rust​​​同样,但禁止访问除​​已初化​​联合字段外字段.

enum U {
A(i32),
B(i64),
}

let u = U::A(10);

结构初化

在D中,结构可​​按顺序​​​初化,也可用​​字段​​名初化:

struct S { int a; int b; int c; int d; }
S x = { 1, 2, 3, 4 };
S y = { b : 3 , a : 5 , c : 2 , d : 10 };

在​​Rust​​中,强制按名字:

struct S {
a: i32, b: i32, c: i32, d: i32,
}

let x = s { 1, 2, 3, 4 }; // 错误.
let y = S { a: 1, b: 2, c: 3, d: 4 }; // 好.

初化数组

在D中,有很多方法可初化数组,包括指定要初化元素索引:

int[3] a = [ 3, 2, 0 ];
int[3] a = [ 3, 2 ];// 未指定,都是0
int[3] a = [ 2 : 0, 0 : 3, 1 : 2 ];
int[3] a = [ 2 : 0, 0 : 3, 2 ];
// 未提供,索引则为前个加1.

​Rust​​​中,既可列出想要​​初化​​​数组的所有值,也可为​​所有数组元素​​指定一个值:

let a1 = [1, 2, 3, 4, 5];
let a2 = [0; 6];

转义串

string file = "c:\\root\\file.c";
string file = r"c:\root\file.c"; // c:\root\file.c
string quotedString = `"[^\\]*(\\.[^\\]*)*"`;
//
let file = "c:\\root\\file.c";
let file = r"c:\root\file.c";

let quoted_string = r#""[^\\]*(\\.[^\\]*)*""#;

不同类型串

string  utf8  = "hello";     // UTF-8 string
wstring utf16 = "hello"; // UTF-16 string
dstring utf32 = "hello"; // UTF-32 string

​秀​​​只支持​​utf8​​.

let str = "hello";

映射枚举到数组

enum COLORS { red, blue, green }

string[ COLORS.max + 1 ] cstring = [
COLORS.red : "red",
COLORS.blue : "blue",
COLORS.green : "green",
];

类似于​​Rust​​​使用​​collect​​宏!这样:

use std::collections::BTreeMap;

#[derive(PartialOrd, Ord, PartialEq, Eq)]
enum Colors {
Red,
Blue,
Green,
}

let cstring: BTreeMap<_, _> = collect![
Colors::Red => "red",
Colors::Blue => "blue",
Colors::Green => "green",
];

创建新类型

D允许从​​现有类型​​​创建​​新类型​​​(强​​typedef​​):

import std.typecons;

alias Handle = Typedef!( void* );
void foo( void* );
void bar( Handle );

Handle h;
foo( h ); // syntax error
bar( h ); // ok

包括,具有默认值:

alias Handle = Typedef!( void* , cast( void* ) -1 );
Handle h;
h = func();
if( h != Handle.init ) {
...
}

在​​Rust​​​中,通过用​​元组​​结构来完成的:

struct Handle(*mut i8);

fn foo(_: *mut i8) {}
fn bar(_: Handle) {}

foo(h); // error
bar(h); // ok

​秀​​要创建默认值:

struct Handle(*mut i8);

impl Default for Handle {
fn default() -> Self {
Handle(std::ptr::null_mut())
}
}

let h = Handle::default();

比较结构

struct A {
int a;
}

if (a1 == a2) { ... }
//
#[derive(PartialEq)]
struct A {
a: i32,
}

if a1 == a2 { ... }

​D​​​隐式实现了比较运算符,​​秀​​​用​​#[derive(PartialEq)]​​.

比较串

string str = "hello";
if( str == "betty" ) {
...
}

if( str < "betty" ) {
...
}
//
let str = "hello";

if str == "betty" {
...
}

if str < "betty" {
...
}

排序数组

D使用通用算法实现:

import std.algorithm;
type[] array;
...
sort( array ); // 原位排序
array.sort!"a>b" // 自定义排序
array.sort!( ( a , b ) => ( a > b ) )//同上

​Rust​​​用稍微不同方法排序,是为"​​切片​​"实现的,可强制转换容器为切片.

let mut array = [3, 2, 1];
array.sort();
array.sort_by(|a, b| b.cmp(a));

遍历数据结构

void foo() {
int a = 10;

void bar() {
a = 20;
}

bar();
}

在​​Rust​​​中,可声明​​嵌套函数​​​,但它们不能捕获​​变量​​,因此用闭包:

fn foo() {
let mut a = 10;

fn bar() {
//a = 20; // 错误.
}
let mut baz = || { a = 20 };//闭包.
baz();
}

可变参数.

import std.stdio;
int sum( int[] values ... ) {
int s = 0;
foreach( int x ; values ) {
s += x;
}
return s;
}

int main() {
writefln( "sum = %d", sum( 8 , 7 , 6 ) );

int[] ints = [ 8 , 7 , 6 ];
writefln( "sum = %d", sum( ints ) );

return 0;
}

​Rust​​​不直接支持​​可变参数​​​,而是建议用​​切片或迭代器​​:

fn sum(values: &[i32]) -> i32 {
let mut res = 0;
for val in values {
res += *val;
}
res
}

fn main() {
println!("{}", sum(&[1, 2, 3]));

let ints = vec![3, 4, 5];
println!("{}", sum(&ints));
}