学了下ziglang,感觉这个语言有些特色,但是目前文档急需提升。主要是看他的language reference,整体上比rust的成熟度还是差的远,因此有很多地方比较confusing。

Array, Struct, Pointer

这里确实比较容易导致一些误解。首先这几个的定义都比较类似,不注意容易引起错误。

比如Array,Array的定义应该就是 [_]u8{...}

var array = [_]u8{ 1,2,3 };

但是你可以定义Slice(指针):

var array_p:[]u8 = &array;

此时array_p是一个pointer,不是一个Array。

不能写:

var array_p:[]u8 = .{1,2,3};

或者;

var array_p:[]u8 = [_]u8{1,2,3};

但是可以这么写:

var array_p: []const u8 = &.{1,2,3};

或者:

var array_p: []const u8 = &[_]u8{1,2,3};

Struct和Array构造匿名完全相同,.{1,2,3}到底是个struct还是array,取决于语句的上下文,比如:

var array_b: [4]u8 = .{1,2,3,4}这样是可以的,但是var array_b: [_]u8 = .{1,2,3,4}这样不行,报错编译器无法推导出数组的长度。但是如果我这么写 var array_b: [4]u8 = .{1.2.3},他又报错说是,不能把一个struct赋值给一个数组,说明此时.{1,2,3}是一个匿名struct而不是数组。那既然长度要求强制一致,为啥不直接从数字的个数推导出来呢?

PS:去社区问了下,答复是说.{} 都是匿名struct/tuple。这种赋值都是一种强制转换(coerce),目前编译器不好强制转换成[_]u8这种类型。

Pointer的类型

*T最普通的类型

[*]T指向many-item,可以进行指针运算.

*[x]T指向一个数组,x不可以省略。该指针支持ptr.len操作,而[*]T不支持,[*]T是裸指针。

[]T指向slice的指针。指针支持ptr.len操作。

感觉中间两种指针,容易让人感觉很迷惑。是否说明zig中的Array是一种特殊的结构体,并不是简单的数组。

Const不是基本类型的修饰器,只能修饰指针或者slice

cosnt i = 1,i is a comptime_int.

const i :i32 = 1, i is a i32 not a const i32

the reason why:

well, yeah, mutability is a property of memory, not of types

it happens that pointers (slices being types of pointers) are types which refer to memory

so they encode that information

but a u32 or whatever is never itself const

merely the memory which represents the u32 is const

The way to check if a variable is a const or not?

1
@typeInfo(@TypeOf(&variable)).Pointer.is_const
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 test {
     var b = i;
     var c: *i32 = &b;
     var d: **i32 = &c;
     try expect(d.* == c);
     playPointer(c);
     try expect(b == 3);
 }

 pub fn playPointer(p: *i32) void {
     std.debug.print("{}\n", .{@TypeOf(p)});
     std.debug.print("{}\n", .{@typeInfo(@TypeOf(&p)).Pointer.is_const});
     p.* = 3; //you can do this
     
     // but you can not do the following, as p it self is a const, however the value p is pointed to is not.
     // as in C++, p is int* const.
     
     // var k:i32 = 1;
     // p = &k; 
 }

to be continued…