八月#
Vala Tutorial#
Basics#
Compile to C
Use GLib type & objecct system
- @
用
@
前缀来允许使用关键字或者数字作为变量名- new
使用
Object obj = new Object()
实例化对象- 注释
C 风格的注释,
/**
是文档注释- 类型
- value types
传值
支持绑定方法 (
ture.to_string()
)
- struct
成员支持 public/private
- enum
朴素的 int 值
- string
"""
跨行字符串
@
前缀类似 Python 的 f-string:
@"$a * $b"
- 切片
正:
foo[7:12]
,负:foo[-4:-2]
- 不可变
string a = "foo"; a[0] = 'b'
不合法- 和其他类型转换
.parse()
和.to_string()
in
操作符string in string
- array
定长数组,同样传值
栈上声明:
int a[10];
堆上(可以
.resize()
):int[] a = new int[10] int[] b = { 2, 4, 6, 8 }
- 切片
支持切片
unowned
用
unowned int[] c = b[1:3]
防止传值- 多维
int[,] c = new int[3,4]; int[,] d = {{2, 4, 6, 8} {3, 5, 7, 9}, {1, 3, 5, 7}};
多维数组无法降维:无法省略任意维的下标
- 追加
+=
- reference types
常常继承
GLib.Object
,基于 reference count 的内存管理,有null
见 OOP 一节
- 静态 cast
C-style,没有 runtime 开销:
int i = 10; float j = (float) i;
- 类型推断
用
var
代替显式的类型声明:var p = new Person(); // same as: Person p = new Person(); var s = "hello"; // same as: string s = "hello"; var l = new List<int>(); // same as: List<int> l = new List<int>(); var i = 10; // same as: int i = 10;
- 创建类型
TODO
- 操作符
- 自操作
++, --, +=, -=, /=, *=, %=, |=, &=, ^=
- 三目运算
true ? 1 : 0
- null coalescing
else if null:
a ?? b
=>a != null ? a : b
- in
需要
.contains()
方法支持,对于 string 是搜索字串
- 控制流
提示
条件判断总是需要 bool,和 C 里只要求非零指有区别
- 循环,支持
break
continue
while (a > b) { a--; } do { a--; } while (a > b); for (int a = 0; a < 10; a++) { stdout.printf("%d\n", a); } foreach (int a in int_array) { stdout.printf("%d\n", a); }
- 分支
if (a > 0) { stdout.printf("a is greater than 0\n"); } else if (a < 0) { stdout.printf("a is less than 0\n"); } else { stdout.printf("a is equal to 0\n"); } switch (a) { case 1: stdout.printf("one\n"); break; case 2: case 3: stdout.printf("two or three\n"); break; default: stdout.printf("unknown\n"); break; }
- 循环,支持
- Language Elements
- 方法
Vala 方法总会被编译成 C 函数:因此总是接受 若干 参数,返回 一个 结果
推荐下划线分割的全小写
不支持重载
- 默认参数
void f(int x, string s = "hello", double z = 0.5) { }
- Nullable value
string? method_name(string? text, Foo? foo, Bar bar) { // ... }
- Delegate type
感觉是用来约束函数签名的
参见
- 匿名函数
(a) => { stdout.printf("%d\n", a); }
- Namespace
- 声明
推荐驼峰:
namespace NameSpaceName { // ... }
不在任何命名空间的对象会被放在全局的匿名命名空间中
命名空间可嵌套声明
- 引用
using
关键字:using NameSpaceName;
"GLib" 命名空间总是默认引用
为了避免歧义,需要从全局空间开始索引,可以使用
global::
前缀
用
class NameSpace1.Test { ... }
可以将 class 声明在特定命名空间中。- Struct
- 声明
推荐驼峰,需要显式设置成员的 access modifier:
struct StructName { public int a; }
- 实例化
Color c1 = Color(); // or Color c1 = {}; Color c2 = { 0.5, 0.5, 1.0 }; Color c3 = Color() { red = 0.5, green = 0.5, blue = 1.0 };
总是在栈上分配,并且在赋值时传值
- Class
总是在堆上分配,并且在赋值时传址
- Interface
Vala 的 interface 可携带默认实现
- Code Attributes
对编译期的指示,形如:
[AttributeName(param1 = value1, param2 = value2, ...)]
[CCode(...)]
:Bindings in vapi files
[DBus(...)]
:Exporting remote interfaces via D-Bus
Object Oriented Programming#
- Access modifier
- public:
No restrictions to access
- private:
(default) Access is limited to within the class/struct definition
- protected:
Access is limited to within the class definition and any class that inherits from the class
- internal:
Access is limited exclusively to classes defined within the same package
- Constructor Overloading
不支持,用以下语法替代:
public class Button : Object { public Button.with_label(string label) {} } new Button.with_label("Click me");
- Destruction
熟悉的语法:
class Button : Object { ~Button() { } }
- Signals
GLib.Object
的信号机制的语法糖:public class Test : GLib.Object { public signal void sig_1(int a); public static void main(string[] args) { var t1 = new Test(); t1.sig_1.connect((t, a) => { stdout.printf("%d\n", a); }); t1.sig_1(5); } } Signal 现在只能是 `public` 的 Code Attributes `[Signal (action=true, detailed=true, run=true, no_recurse=true, no_hooks=true)]`
- Properties
Getter & Setter:
class Person : Object { /* Property with standard getter and setter and default value */ public int age { get; set; default = 32; } }
Code Attributes:
[Description(nick = "age in years", blurb = "This is the person's age in years")] [CCode(notify = false)]
Notify:
alice.notify["age"].connect((s, p) => { stdout.printf("age has changed\n"); });
- Inheritance
GObject
的实现决定了 Vala 只支持单继承。base()
即 python 里的
super()
- Abstract Classes
用
abstract
声明抽象类,或者用virtual
提供默认实现。用override
提供实现。
Interfaces
ThinkPad Carbon X1C Gen9#
- date:
2021-08
素描群作业点评#
- date:
2021-08-27
发根垂直于头皮
如果你有任何意见,请在此评论。 如果你留下了电子邮箱,我可能会通过 回复你。