Colgm 中的字面量都有默认类型。
- 整数:
i64- 以
0x开头的整数被视为十六进制整数,类型为u64 - 以
0o开头的整数被视为八进制整数,类型为u64
- 以
- 浮点数:
f64 - 布尔值:
bool,有两个关键字true和false - 常量字符串:
const i8* - 数组:其基本类型的指针
- 具有此类型的变量是不可变的
- 如果基本类型不是常量,则数组中的元素是可变的
- nil:特殊指针
nil,类型为i8*
func main() -> i32 {
var a = 1; // i64
var b = 2.0; // f64
var c = "hello world!"; // const i8*
var d = 'd'; // i8
var e = [i8; 128]; // (array) i8*
var f = true; // bool
var g = nil; // i8*
var h = 0x7fffffff; // u64
var i = 0o777; // u64
return 0;
}Colgm 支持一种名为自动类型转换的特性。
请注意,此特性仅适用于字面量。
例如,虽然 1 是类型为 i64 的整数字面量,
但在以下情况下它将被转换为 i32:
-
带有类型声明的定义:
var a: i32 = 1; // i64 转 i32 var b: i64* = nil; // i8* 转 i64*
-
函数调用:
pub func foo(a: i32, b: i32) -> i32 { return a + b; } func main() -> i32 { return foo(1, 2); // 1 i64 => i32, 2 i64 => i32 }
-
赋值:对于类型为
i16的a,a = 1;中的1将被转换为i16 -
计算:对于类型全为
i32的变量,a + b * 16 - d / e中的16将被转换为i32 -
返回语句:对于返回类型为
i32的函数,return 1;中的1将被转换为i32
完整示例:
pub func test(arg: u32) -> u8 {
return arg => u8;
}
pub func main() -> i32 {
var a: i32 = 1; // i64(1) => i32
var b: i64* = nil; // i8*(nil) => i64*
if (a < 10) { // i64(10) => i32
return 1; // i64(1) => i32
} else if (a != 1) { // i64(1) => i32
return -1; // i64(-1) => i32
} //
var c = 'a'; //
c += 1; // i64(1) => i8
//
var d = 1.0; // f64
var e: f32 = 2.71; // f64(2.71) => f32
//
test(42); // i64(42) => u32
return 0; // i64 => i32
}在初始化结构体时也可用:
struct Example {
a: u64,
next: Example*
}
func main() -> i32 {
var s = Example {
a: 1, // i64(1) => u64
next: nil // i8*(nil) => Example*
}; //
return 0; // i64(0) => i32
}Colgm 支持数组的写法。数组可以通过多种方法来初始化。 但是必须要注意,空数组的初始化必须声明类型。
func main() -> i32 {
var a = [1, 2, 3]; // [i64; 3]
// ^ => 基础类型由第一个元素的类型决定
// ^^^^^^^ => 数组大小由元素数量决定
// [i32; 1024] 并且第一个元素是 0
var b: [i32; 1024] = [0 => i32];
// error: 无法推导数组类型
var c = [];
return 0;
}Colgm 允许以下算术运算符:
a + b; // 加
a - b; // 减
a * b; // 乘
a / b; // 除
a % b; // 模,仅用于整数类型Colgm 支持以下位运算符,仅支持整数类型:
a | b; // 位或
a ^ b; // 位异或
a & b; // 位与Colgm 支持基本逻辑运算符:== != < <= > >=。
仅允许布尔类型。
and/or 的逻辑运算符都有两种语法:
1 == 1 and 2 == 2 && 3 == 3;
// ^^^ ^^ 相同的逻辑与
1 == 1 or 2 == 2 || 3 == 3;
// ^^ ^^ 相同的逻辑或Colgm 允许两种定义方式。 没有类型声明的定义将使用类型推断, 所以确保初始值的类型是您想要的。
var variable: type = expression; // 带类型
var variable = expression; // 不带类型Colgm 不允许变量名覆盖。
var a: i32 = 1;
if (1 == 1) {
var a: f64 = 1;
// ^^^^^^ 变量名覆盖(name shadowing)
}但是下面这个样例是允许的。
if (1 == 1) {
var b = 1;
} else {
var b = 1.0;
}Colgm 允许以下赋值运算符:
a += b; // 加
a -= b; // 减
a *= b; // 乘
a /= b; // 除
a %= b; // 模,仅用于整数类型
a |= b; // 位或,仅用于整数类型
a ^= b; // 位异或,仅用于整数类型
a &= b; // 位与,仅用于整数类型While 循环与 C 语言中的相同。
while (1 == 1) {
...
continue;
break;
}条件语句与 C 语言中的相同。
语法与 C 语言相同,
除了关键字 elsif,它与 else if 用法相同。
if (1 == 1) {
...
} elsif (1 == 1) {
...
} else if (1 == 1) {
...
} else {
...
}Colgm 支持 match 关键字。
Match 语句仅接受枚举类型。每个分支都不会 fall through。
默认分支是 _。
match (variable) {
EnumType::a => ...;
EnumType::b => { ... }
_ => { ... }
}for (var i = 0; i < 10; i += 1) {}
// 等同于:
//
// var i = 0;
// while (i < 10) {
// i += 1;
// }foreach (var i; container) {}
// 等同于:
//
// for (var tmp_i = container.iter(); !tmp_i.is_end(); tmp_i = tmp_i.next()) {
// ...
// }forindex (var i; container) {}
// 等同于:
//
// for (var tmp_i: u64 = 0; tmp_i < container.iter_size(); tmp_i += 1) {
// ...
// }关于自动类型转换,请参见自动类型转换。
与 Rust 有点类似,使用 => 代替 as:
use std::libc::malloc;
func main() -> i32 {
var res1 = 0 => i32;
var res2: i32 = 0; // 与上面相同,使用自动类型转换
var ptr1 = malloc(1024) => i16*;
return res1 + res2;
}结构体与 C 语言中的相同。 目前不支持 RAII。 因此,在将一个结构体移动到另一个结构体时要小心, 这将进行__浅__拷贝。
struct StructName {
field1: i64,
field2: i64
}
// 使用泛型
struct StructWithGeneric<T> {
__size: i64,
__data: T*
}Colgm 支持结构体初始化器, 某些成员字段可以省略。 但要注意不要初始化所有字段。 如果使用了未初始化的字段, 将发生未定义行为。
目前 Colgm 将结构体的默认数据设置为 llvm 的 zeroinitializer。
func test() {
var s1 = StructName {};
var s2 = StructName { field1: 1 };
var s3 = StructName { field1: 1, field2: 2 };
}Colgm 支持 impl 关键字。
对于方法,第一个参数是 self,
它是指向结构体的指针。
对于静态方法,第一个参数不应该是 self。
impl StructName {
func method(self) -> type {
...
return ...;
}
func static_method() -> type {
...
return ...;
}
}
// 实现泛型
impl StructWithGeneric<T> {
...
}枚举与 C++ 语言中的 enum class 相同。
默认情况下,枚举的第一个成员是 0,
下一个成员是 1,然后是 2,依此类推。
但您可以指定每个成员的值。
enum EnumExample {
kind_a,
kind_b,
kind_c
}
enum EnumSpecified {
kind_a = 0x100,
kind_b = 0x200,
kind_c = 0x300
}有一些特殊需求很难用常规的写法满足,比如你想要知道当前程序的编译时间戳, 此时我们需要一个字符串常量来保存编译时间戳,但是很难通过常规写法获取。 于是编译器提供了以下内建函数来获取编译时间戳:
use std::io::{ io };
fn main() -> i32 {
io::stdout().out(__time__()).endln();
return 0;
}现在 colgm 支持以下这些内建函数:
__time__
条件编译是一种特性, 允许您根据特定条件编译代码。 例如,跨平台问题可以通过条件编译解决。
#[enable_if(target_os = "linux")]
pub enum flag {
O_RDONLY = 0x000,
O_WRONLY = 0x001,
O_RDWR = 0x002,
O_CREAT = 0x040,
O_EXCL = 0x080,
O_TRUNC = 0x200,
O_APPEND = 0x400
}目前支持的条件编译选项:
#[enable_if(target_os = "xx", arch = "xx)]target_os: `linux", "windows", "macos"arch: `x86_64", "aarch64"
#[is_trivial(T)]#[is_non_trivial(T)]#[is_pointer(T)]#[is_non_pointer(T)]
Colgm 搜索库文件的顺序是:
- 通过
-L/--library选项传入的库路径 - 当前目录 (
.) - 环境变量
$PATH
如果仍然无法确认搜索顺序,可以添加 --view-path 选项来查看。
