当前位置: 首页 > news >正文

Vala编程语言教程-数据类型

核心数据类型

        Vala 的数据类型分为两大类别:

类型行为特性
值类型赋值时创建副本(如 intstruct
引用类型赋值时共享对象,新标识符指向同一内存(如 classstring

        常量定义使用 const 修饰符,命名规范为全大写加下划线:

const double MU_BOHR = 927.400915E-26;


值类型

Vala 支持以下基础值类型:

类别类型示例
字节类型char (历史遗留名,实际为字节), uchar
Unicode字符unichar (32位)
整数类型intuintlongulongshortushort
定长整数int8uint16int32uint64 等(数字代表位数)
浮点数floatdouble
布尔值bool (仅 true/false)
结构体struct 自定义复合类型
枚举enum (底层为整数值,非类形式)

示例代码‌:

unichar c = 'ü';                          // Unicode 字符
float percentile = 0.75f;                 // 单精度浮点数
struct Vector {                           // 三维向量结构体
    public double x;
}
enum WindowType { TOPLEVEL, POPUP }       // 窗口类型枚举

类型操作‌:

ulong size = sizeof(int32);               // 获取类型字节数(int32 为 4 字节)
int max_val = int.MAX;                    // 获取 int 最大值(2147483647)

字符串(引用类型)

核心特性‌:

  • 编码‌:UTF-8,不可变(Immutable)
  • 声明方式‌:
    string text = "标准字符串";               // 支持转义符如 \n, \t
    string raw_str = """                    // 原始字符串(保留格式,不转义)
        多行文本,可直接包含 "引号",
        换行和缩进均保留。
    """;
    

字符串模板‌:

int a = 6, b = 7; 
string expr = @"$a × $b = $(a * b)"; // 输出 "6 × 7 = 42" 

操作与方法‌:

操作示例结果
切片"hello"[1:4]"ell"
包含判断if ("ere" in "Able was I...")返回 true
类型转换int.parse("42") → 42字符串转数值
控制台交互stdout.printf("%s", str)格式化输出
string input = stdin.read_line()读取用户输入

索引访问‌(Vala ≥0.11):

uint8 byte = text[3]; // 获取第3个字节(索引从0开始)


String与其他类型间的相互转换:

bool b = bool.parse("false");           // => false
int i = int.parse("-52");               // => -52
double d = double.parse("6.67428E-11"); // => 6.67428E-11
string s1 = true.to_string();           // => "true"
string s2 = 21.to_string();             // => "21"

判断是否是字符串的子串:

if ("ere" in "Able was I ere I saw Elba.") ...

数组

声明与初始化‌:

int[] a = new int[10];
int[] b = { 2, 4, 6, 8 };

切片操作:

int[] c = b[1:3];     // => { 4, 6 }

核心属性‌:

特性说明
长度获取int len = arr.length
动态扩容arr.resize(15)
值类型数组存储实际数据(如 int[] 每个元素独立)
引用类型数组存储对象指针(如 string[] 共享对象)

内存特性‌:

  • 数组在内存中连续存储,可通过指针操作高效访问。
  • 多维数组以行优先(Row-major)顺序存储。

‌创建多维数组:

int[,] c = new int[3,4];
int[,] d = {{2, 4, 6, 8},
            {3, 5, 7, 9},
            {1, 3, 5, 7}};
d[2,3] = 42;

多维数组各维度大小:

int[,] arr = new int[4,5];
int r = arr.length[0];  // => 4 第一维的长度
int c = arr.length[1];  // => 5 第二维的长度

与其他语言的区别:

        不支持[][]和切片操作:

int[,] arr = {{1,2},
             {3,4}};
int i = arr[0,1]; // work   a = 1
int j = arr[0][1]; // won't work
int[] b = arr[0];  // won't work
int[] c = arr[0,];  // won't work
int[] d = arr[:,0];  // won't work
int[] e = arr[0:1,0];  // won't work
int[,] f = arr[0:1,0:1];  // won't work

动态扩容:

        Vala 允许使用 += 操作符实现数组的‌动态扩容‌,但需遵循以下规则:

int[] arr = {1, 2, 3};
arr += 4;    // 合法:局部数组 → 变为 [1,2,3,4]
arr += 5,6;  // 批量追加 → [1,2,3,4,5,6]

move方法:

Vala 提供 move(src, dest, length) 方法实现‌数组元素块移动‌,具体行为如下:

int[] arr = {1, 2, 3, 4, 5};

// 将索引 1 开始的 2 个元素移动到索引 3 处
arr.move(1, 3, 2); 

// 原位置 1-2 被填充 0 → [1, 0, 0, 2, 3]

引用类型

        所有声明为类的类型均为引用类型,无论它们是否继承自 GLib 的 Object。Vala 会确保当以引用方式传递对象时,系统将跟踪当前存活的引用数量以自动管理内存。未指向任何对象的引用值为 null。这一点与java类似。

/* 定义一个类 */
class Track : GLib.Object {             /* 继承自'GLib.Object' */
    public double mass;                 /* pbulic 字段 */
    public double name { get; set; } /* public 属性 */
    private bool terminated = false; /* 私有字段 */
    public void terminate() {           /* 公共方法 */
        terminated = true;
    }
}

类型转换

        Vala支持以下方式的类型转换,适用于所有vala数据类型:

int i = 10;
float j = (float) i;

类型推断

        Vala 有一种称为类型推断的机制,只要使用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;

        而且类型推断对于具有泛型类型参数的类型特别有用:

MyFoo<string, MyBar<string, int>> foo = new MyFoo<string, MyBar<string, int>>();
// 可以使用以下方式定义foo
var foo = new MyFoo<string, MyBar<string, int>>();

从其他类型定义新类型

/* 给一个基础类型int定义一个别名Integer (等同于C语言中的 typedef int Integer)*/
[SimpleType]
public struct Integer : uint {
}
/* 给GLib.List<GLib.Value>定义别名: ValueList */
public class ValueList : GLib.List<GLib.Value> {
    [CCode (has_construct_function = false)]
    protected ValueList ();
    public static GLib.Type get_type ();
}

相关文章:

  • 【iOS】SwiftUI 路由管理(NavigationStack)
  • 深入理解 Linux 的 top 命令:实时监控系统性能
  • Unity 解决TMP_Text 文字显示异常的问题
  • 手势调控屏幕亮度:Python + OpenCV + Mediapipe 打造智能交互体验
  • 记事本(基于JAVAGUI界面)
  • 一次模拟Windows挖矿病毒应急响应的流程及思路
  • Linux系统管理与编程05:网络管理番外篇
  • 一篇最全Python 爬虫超详细讲解(零基础入门,适合小白)
  • AUTOSAR Communication Services - COM:(一)COM相关功能、API整理与序列图
  • 文献阅读篇#1:C会/期刊的改进YOLO论文应放弃即插即用,至少要学会简单融合拼接(1)
  • 逐光之路:我在特种设备作业考试中的成长蜕变
  • Joker靶机实战攻略
  • 逻辑派G1 6层高速板学习
  • 连接不上雷电模拟器,adb连接不上问题的解决办法
  • Billu_b0x靶机实战攻略
  • JS逆向案例-HIKVISION-视频监控的前端密码加密分析
  • 分享一个项目中遇到的一个算法题
  • SPI 总线协议
  • Pytest项目_day01(HTTP接口)
  • 微服务即时通信系统---(五)框架学习
  • “免签圈”扩容,旅游平台:今年以来巴西等国入境游订单显著增加
  • 商务部回应稀土出口管制问题
  • “一百零一个愿望——汉字艺术展”亮相意大利威尼斯
  • 夜读丨读《汉书》一得
  • 上海市重大工程一季度开局良好,崇明线等按既定计划加快建设
  • 深圳中院回应“退休夫妻月入1.2万负债1.2亿”:其自述因经营不善负债