仓颉基础语法与数据类型深度解析
·
目 录
摘要
仓颉的语法设计既保留了 C 族语言的熟悉性,又融入了现代语言的表达力。本文详解基础语法、原始类型、复合类型、类型转换,通过丰富代码示例帮助初学者快速上手,为学习高阶特性奠定基础。
一、语言基础语法
1.1 变量与常量
// 常量声明(编译时已知,不可变)
const MAX_SIZE: Int32 = 100
const PI: Float64 = 3.14159
// 可变变量
var age: Int32 = 25
age = 30 // ✓ 允许
// 不可变变量(let 绑定)
let name: String = "Alice"
// name = "Bob" // ✗ 编译错误
// 类型推断
let count = 42 // 推断为 Int32
let factor = 1.5 // 推断为 Float64
let message = "Hi" // 推断为 String
1.2 注释风格
// 单行注释
let x = 10 // 行尾注释
/*
多行注释
可以跨越多行
*/
/*! 文档注释 - 会被文档生成器读取 */
func example() {
// ...
}
/// 文档注释 - 用于函数/类型前
/// @param input 输入参数
/// @return 返回值说明
func process(input: String): String {
return input.toUpperCase()
}
二、原始数据类型详解
2.1 整数类型
// 不同位宽的整数
let byte_val: Int8 = 127
let short_val: Int16 = 32000
let int_val: Int32 = 2_147_483_647 // 下划线便于阅读
let long_val: Int64 = 9_223_372_036_854_775_807
// 无符号整数
let unsigned: UInt32 = 4_294_967_295
// 溢出检查(发布模式自动禁用)
let result = byte_val + 1 // 调试模式会检查溢出
// 进制表示
let decimal = 255
let hex = 0xFF
let binary = 0b11111111
let octal = 0o377
2.2 浮点数类型
// 浮点数类型
let single: Float32 = 3.14
let double: Float64 = 3.14159265359
// 科学计数法
let large = 1.23e10 // 1.23 × 10^10
let small = 1.5e-5 // 0.000015
// 特殊值
let infinity = Float64.POSITIVE_INFINITY
let neg_infinity = Float64.NEGATIVE_INFINITY
let not_a_number = Float64.NaN
// 浮点数比较(需谨慎)
func almostEqual(a: Float64, b: Float64, epsilon: Float64 = 1e-9): Bool {
return (a - b).abs() < epsilon
}
2.3 布尔与字符
// 布尔类型
let isActive: Bool = true
let isEmpty: Bool = false
// 布尔运算
let result1 = true && false // 逻辑与
let result2 = true || false // 逻辑或
let result3 = !true // 逻辑非
// 字符类型
let char_a: Char = 'A'
let char_emoji: Char = '😀'
let char_code = char_a.toInt32() // 65
// 字符串类型
let str = "Hello"
let multiline = """
第一行
第二行
第三行
"""
三、复合数据类型
3.1 数组类型(Array)
// 数组声明与初始化
let arr1: Array<Int32> = [1, 2, 3, 4, 5]
let arr2 = [10, 20, 30] // 类型推断
let arr3 = Array<String>(capacity: 10) // 指定容量
// 数组访问与修改
var numbers = [1, 2, 3]
println(numbers[0]) // 输出: 1
numbers[1] = 20 // 修改元素
numbers.append(4) // 追加元素
numbers.insert(0, at: 0) // 在索引 0 处插入
// 数组遍历
for (index, value) in numbers.enumerated() {
println("Index: \(index), Value: \(value)")
}
// 数组操作
let doubled = numbers.map { x => x * 2 }
let filtered = numbers.filter { x => x > 2 }
let sum = numbers.reduce(0) { acc, x => acc + x }
// 切片操作
let slice = numbers[0..<3] // 获取前 3 个元素
let tail = numbers[2...] // 从索引 2 到末尾
3.2 字典类型(Dictionary)
// 字典声明与初始化
let dict1: Dictionary<String, Int32> = ["apple": 5, "banana": 3]
let dict2 = ["name": "Alice", "city": "Beijing"]
// 字典访问
if let value = dict1["apple"] {
println("Apple count: \(value)")
}
// 字典修改
var settings = ["theme": "dark", "language": "zh"]
settings["theme"] = "light"
settings["newKey"] = "newValue"
// 字典遍历
for (key, value) in settings {
println("\(key): \(value)")
}
// 字典操作
let keys = settings.keys
let values = settings.values
let count = settings.count
3.3 元组类型(Tuple)
// 元组声明
let point: (Int32, Int32) = (10, 20)
let person = (name: "Alice", age: 28, city: "Beijing")
// 元组访问
let x = point.0
let y = point.1
let name = person.name
let age = person.age
// 元组作为函数返回值
func divideWithRemainder(a: Int32, b: Int32): (quotient: Int32, remainder: Int32) {
return (a / b, a % b)
}
let (q, r) = divideWithRemainder(17, 5)
println("17 ÷ 5 = \(q) 余 \(r)") // 输出: 3 余 2
// 元组解构
let (firstName, lastName, _) = ("John", "Doe", "Jr")
// _ 用于忽略不需要的值
四、字符串处理
4.1 字符串基础
// 字符串声明
let str1 = "Hello, Cangjie!"
let str2: String = "World"
// 字符串拼接
let greeting = "Hello" + " " + "World"
let formatted = "Value: \(42)" // 字符串插值
// 多行字符串
let doc = """
这是一个多行字符串
可以包含多行文本
通常用于文档或 SQL
"""
// 字符串长度与访问
let text = "Cangjie"
println(text.count) // 字符计数
println(text.length) // 字节长度
println(text[0]) // 访问第一个字符
// 字符串转义
let escaped = "Line 1\nLine 2\tTabbed"
let path = "C:\\Users\\Name"
4.2 字符串操作
var text = "Hello World"
// 大小写转换
let upper = text.toUpperCase() // HELLO WORLD
let lower = text.toLowerCase() // hello world
// 字符串查询
let contains = text.contains("World") // true
let startsWith = text.startsWith("Hello") // true
let endsWith = text.endsWith("d") // true
let index = text.find("World") // 6
// 字符串提取
let substring = text.substring(0, 5) // "Hello"
let replaced = text.replace("World", "Cangjie") // "Hello Cangjie"
// 字符串分割与拼接
let parts = "a,b,c".split(",")
let joined = ["x", "y", "z"].join("-") // "x-y-z"
// 字符串trim
let padded = " spaces "
let trimmed = padded.trim()
五、类型转换
5.1 显式类型转换
// 整数转换
let int_val: Int32 = 42
let int64_val: Int64 = Int64(int_val)
let uint_val: UInt32 = UInt32(int_val)
// 浮点数转换
let float_val: Float32 = Float32(3.14)
let double_val: Float64 = Float64(float_val)
// 数值到字符串
let str_from_int = String(42)
let str_from_float = String(3.14)
// 字符串到数值
if let num = Int32.parse("42") {
println("Parsed: \(num)")
}
if let float = Float64.parse("3.14") {
println("Float: \(float)")
}
// 字符转整数
let char = 'A'
let ascii = char.toInt32() // 65
let from_ascii = Char(65) // 'A'
5.2 as 运算符与类型检查
// 子类型向上转换(always safe)
class Animal {}
class Dog: Animal {}
let dog = Dog()
let animal: Animal = dog as Animal
// 类型转换与类型检查
func describe(_ obj: Any) {
if let str = obj as? String {
println("String: \(str)")
} else if let num = obj as? Int32 {
println("Int: \(num)")
} else {
println("Other type")
}
}
describe("Hello") // 输出: String: Hello
describe(42) // 输出: Int: 42
六、完整示例:数据类型综合应用
// 定义一个学生信息结构体
struct Student {
var id: Int32
var name: String
var scores: Array<Float32>
var info: (grade: Int32, class: Int32)
}
// 为 Student 实现方法
impl Student {
// 计算平均分
func averageScore(): Float32 {
let sum = scores.reduce(0.0) { acc, x => acc + x }
return sum / Float32(scores.count)
}
// 返回学生信息
func description(): String {
let avg = averageScore()
return "\(name) - 平均分: \(avg)"
}
// 判断是否优秀(平均分 >= 85)
func isExcellent(): Bool {
return averageScore() >= 85.0
}
}
func main() {
// 创建学生
var student = Student(
id: 1001,
name: "Alice",
scores: [85.5, 92.0, 88.5, 95.0],
info: (grade: 10, class: 1)
)
println(student.description())
if student.isExcellent() {
println("\(student.name) 是优秀学生!")
}
// 创建学生数组
var students = [Student]()
students.append(student)
// 统计优秀学生
let excellent = students.filter { s => s.isExcellent() }
println("优秀学生数: \(excellent.count)")
// 按平均分排序
students.sort { a, b =>
a.averageScore() > b.averageScore()
}
}
七、类型系统最佳实践
7.1 何时使用各类型
| 场景 | 推荐类型 | 原因 |
|---|---|---|
| 整数计数 | Int32 | 平衡性能与范围 |
| 大整数 | Int64 | 防止溢出 |
| 金融计算 | Decimal(第三方库) | 精度高 |
| 网络编程 | UInt32 | 无符号更方便 |
| 科学计算 | Float64 | 精度更高 |
7.2 避免常见错误
// ✗ 错误:浮点数精度问题
let x = 0.1 + 0.2 // 0.30000000000000004
if x == 0.3 { println("Equal") } // 不会执行
// ✓ 正确:使用 epsilon 比较
func floatEqual(a: Float64, b: Float64): Bool {
return (a - b).abs() < 1e-9
}
// ✗ 错误:忽视整数溢出
let large: Int32 = 2_147_483_647
let overflow = large + 1 // 溢出!
// ✓ 正确:使用更大的类型
let large: Int64 = 2_147_483_647
let safe = large + 1
// ✗ 错误:数组索引越界
let arr = [1, 2, 3]
println(arr[10]) // 运行时崩溃
// ✓ 正确:检查边界
if index < arr.count {
println(arr[index])
}
八、总结与进阶建议
✅ 关键要点
- 8 种基础类型覆盖日常编程需求
- 复合类型(数组、字典、元组)灵活强大
- 类型系统严格在编译期捕获错误
- 字符串作为一级类型,操作丰富
📚 进阶方向
- 学习 Trait 和 泛型实现代码复用
- 深入 所有权系统理解内存管理
- 掌握 模式匹配优雅处理复杂情况
参考链接
更多推荐



所有评论(0)