d对比rust下

原文下

取类型大小(字节)

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));
}
posted @   zjh6  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示