八月#

Vala Tutorial#

URL:

https://wiki.gnome.org/Projects/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

发根垂直于头皮

评论

如果你有任何意见,请在此评论。 如果你留下了电子邮箱,我可能会通过 回复你。