Julia 教程
Julia 教程
Julia 是一门面向科学计算的高性能动态编程语言,语法优雅如 Python,性能媲美 C 语言。它专为数值分析、机器学习、数据科学设计,是 MATLAB、R 和 Python 的科学计算强力替代品。
Julia 的特点
- 快:JIT 编译,接近静态编译语言的速度
- 动态类型:像 Python 一样易写,无需声明类型也可运行
- 多分派:函数根据所有参数类型选择实现
- 科学计算原生:线性代数、微分方程、优化内置支持
- 可调用 C/Fortran:无缝调用底层库
典型应用
- 数值模拟与科学计算
- 机器学习与数据科学(Flux.jl、DataFrames.jl)
- 金融建模与量化分析
- 生物信息学、物理、工程仿真
Hello World
println("Hello, Julia!")
# 输出: Hello, Julia!
学习路线
- 环境安装与交互式命令
- 基本语法、数组、元组、数据类型
- 运算符、数学函数、字符串、正则
- 函数、流程控制、字典集合
- 日期时间、文件读写、元编程
Julia 社区生态活跃(JuliaHub、包管理器 Pkg),适合学术与工业计算。
Julia 语言环境安装
Julia 语言环境安装
1. 官方安装
访问 julialang.org 下载对应平台安装包:
# macOS (Homebrew) brew install julia # Ubuntu sudo apt install julia # 版本可能较旧 # 推荐从官网下载 tar.gz 解压 # Windows # 下载 .exe 安装包,或使用 winget install julia
2. 验证安装
julia --version # julia version 1.10.0
3. 交互式 REPL
$ julia
julia> println("hello")
hello
julia> 1 + 1
2
4. 安装 IDE
- VS Code:安装 Julia 扩展(官方),支持调试、补全、绘图集成
- Juno:Atom 编辑器插件(已停止维护)
- Jupyter:安装 IJulia 包后可在 notebook 中使用
# 在 Julia REPL 中安装 IJulia
julia> using Pkg
julia> Pkg.add("IJulia")
5. 包管理器 Pkg
julia> Pkg.add("DataFrames") # 添加包
julia> Pkg.update() # 更新所有包
julia> Pkg.status() # 查看已安装包
julia> Pkg.rm("DataFrames") # 移除包
Julia 交互式命令
Julia 交互式命令
1. REPL 模式
Julia REPL 有四种模式,按不同按键进入:
| 模式 | 提示符 | 说明 |
|---|---|---|
| Julia 模式 | julia> | 默认模式,执行 Julia 代码 |
| 帮助模式 | help?> | 按 ? 进入,查询函数文档 |
| Shell 模式 | shell> | 按 ; 进入,执行系统命令 |
| 包模式 | pkg> | 按 ] 进入,Pkg 包管理 |
2. 常用命令
julia> ?println # 帮助模式查文档 julia> ;ls # shell 模式执行 ls julia> ]add DataFrames # 包模式安装
3. 便捷操作
julia> ans # 上次计算结果
julia> println("hi"); println("world") # 分号分隔
julia> 2^10 # 幂运算 = 1024
# 特殊字符输入:输入 \alpha 再按 Tab
julia> \alpha # 变成 α
julia> \pi # 变成 π
# Unicode 数学符号
julia> α = 0.5
4. 退出与快捷键
exit() # 退出 REPL Ctrl+D # 退出 Ctrl+C # 中断当前计算 Ctrl+L # 清屏 ↑ ↓ # 历史命令
5. 运行脚本文件
$ julia script.jl # 运行脚本 $ julia -e "println(1+1)" # 直接执行表达式 $ julia -i script.jl # 执行后进入交互模式
Julia 基本语法
Julia 基本语法
1. 变量与赋值
x = 10 # 整数 y = 3.14 # 浮点 name = "Julia" # 字符串 flag = true # 布尔 # 一次赋值多个 a, b = 1, 2 # 交换变量 a, b = b, a # 变量名可用 Unicode 变量 = "中文变量名" π = 3.14159
2. 注释
# 单行注释
#= 多行注释
可以跨行 =#
# 文档字符串(在函数/类型前)
"""
函数说明
"""
3. 打印输出
print("不换行")
println("带换行")
println("插值: x = $x, 表达式: $(x + 1)")
# 格式化
println("PI = %.2f" % 3.14159) # PI = 3.14
using Printf
@printf("值: %5.2f\n", 3.14159)
4. 类型与转换
Int(3.14) # 3 Float64(10) # 10.0 string(100) # "100" parse(Int, "42") # 42 typeof(10) # Int64 typeof(3.14) # Float64
5. 常量
const MAX = 100 # 重新赋值会警告
Julia 数组
Julia 数组
1. 创建数组
# 一维数组 a = [1, 2, 3, 4] b = Int[] # 空数组 c = [1.0, 2.0, 3.0] # 浮点数组 # 二维数组(矩阵) m = [1 2 3; 4 5 6] # 2行3列 println(size(m)) # (2, 3) # 推导式 squares = [i^2 for i in 1:5] # [1,4,9,16,25] even = [x for x in 1:10 if x % 2 == 0]
2. 访问与修改
a = [10, 20, 30, 40] a[1] # 10(索引从 1 开始!) a[end] # 40 a[2:3] # [20, 30] a[[1, 3]] # 按索引列表取值 a[1] = 99 # 修改 # 矩阵索引 m[1, 2] # 第1行第2列 m[2, :] # 第2行 m[:, 1] # 第1列
3. 常用操作
push!(a, 50) # 末尾添加 pop!(a) # 末尾弹出 pushfirst!(a, 5) # 开头添加 append!(a, [6,7])# 批量添加 length(a) # 长度 sum(a), mean(a) # 求和、均值(Statistics 包) sort(a) # 排序 reverse(a) # 反转 unique(a) # 去重 in(10, a) # 判断包含
4. 遍历
for x in a
println(x)
end
# 带索引
for (i, x) in enumerate(a)
println("$i -> $x")
end
Julia 元组
Julia 元组
1. 创建元组
t = (1, "hello", 3.14) t2 = (1, 2, 3) # 小括号创建 t3 = (1, ) # 单元素元组(注意逗号) # 命名元组 nt = (name="Julia", version=1.10) nt.name # Julia nt.version # 1.10
2. 访问元素
t = (10, 20, 30)
t[1] # 10
t[1:2] # (10, 20)
# 解构
a, b, c = t
println("$a $b $c") # 10 20 30
# 忽略部分值
x, _, z = t # _ 表示忽略
3. 元组特性
- 不可变:创建后不能修改元素
- 可包含不同类型
- 可作为函数返回值,一次返回多个值
4. 函数返回多个值
function divmod2(a, b)
return div(a, b), mod(a, b)
end
q, r = divmod2(17, 5)
println("商=$q 余=$r") # 商=3 余=2
5. 遍历与操作
for (i, v) in enumerate(("a", "b", "c"))
println("$i: $v")
end
length(("a", "b")) # 2
("a", "b") == ("a", "b") # true(值相等)
Julia 数据类型
Julia 数据类型
1. 数值类型
# 整数 Int8, Int16, Int32, Int64, Int128 UInt8, UInt16, UInt32, UInt64 # 无符号 # 浮点 Float16, Float32, Float64 # 特殊值 Inf # 正无穷 -Inf # 负无穷 NaN # 非数字 missing # 缺失值 x = 10 println(typeof(x)) # Int64 println(typemax(Int8)) # 127
2. 布尔与字符
true, false
'c' # 字符
typeof('a') # Char
# 字符串连接
"Hello" * " World" # Hello World
"Hi" ^ 3 # HiHiHi
3. 字符串类型
s = "Julia" length(s) # 5(字符数) sizeof(s) # 字节数 s[1] # 'J'(UTF-8 索引) uppercase(s) # JULIA lowercase(s) # julia split(s, "u") # ["J", "lia"] join(["a","b"], "-")# "a-b"
4. 类型层次
# 抽象类型 vs 具体类型
Number # 抽象类型:所有数值的父类
Integer # 抽象类型
AbstractString # 字符串抽象类型
Any # 顶层类型
# 判断
isa(10, Int64) # true
isa("s", Number) # false
10 isa Integer # true
supertype(Int64) # Signed
5. 类型转换
convert(Float64, 10) # 10.0 Float64(10) # 10.0 Int(3.9) # 3(截断) round(3.7) # 4.0
Julia 复数和有理数
Julia 复数和有理数
1. 复数(Complex)
z1 = 1 + 2im # im 是虚数单位
z2 = 3 - 1im
println(typeof(z1)) # Complex{Int64}
# 运算
z1 + z2 # 4 + 1im
z1 * z2 # 5 + 5im
z1 / z2 # 0.1 + 0.7im
# 常用函数
abs(z1) # 模长 √5
angle(z1) # 辐角(弧度)
real(z1) # 实部 1
imag(z1) # 虚部 2
conj(z1) # 共轭 1 - 2im
# 创建方式
z3 = complex(1, 2)
z4 = exp(im * π) # 欧拉公式 ≈ -1.0 + 0im
2. 有理数(Rational)
r1 = 1 // 3 # 有理数 1/3
r2 = 2 // 4 # 自动化简为 1//2
println(typeof(r1)) # Rational{Int64}
r1 + r2 # 5//6
r1 * r2 # 1//6
float(r1) # 0.3333333333333333
numerator(r1) # 分子 1
denominator(r1) # 分母 3
3. 精度注意
# 浮点精度问题 0.1 + 0.2 # 0.30000000000000004 # 有理数精确 1//10 + 2//10 # 3//10(精确) # 高精度浮点 using DecFP BigFloat(1) / 3 # 高精度 1/3
Julia 基本运算符
Julia 基本运算符
1. 算术运算符
7 + 3 # 10 7 - 3 # 4 7 * 3 # 21 7 / 3 # 2.3333333333333335(浮点) 7 ÷ 3 # 2(整除,输入 \div Tab) 7 % 3 # 1(取余) 7 ^ 2 # 49(幂) 2^10 # 1024 # 复合赋值 x = 5 x += 3 # x = 8 x *= 2 # x = 16
2. 比较运算符
1 == 1 # true 1 != 2 # true 1 < 2 # true 2 <= 2 # true 1 === 1 # 对象同一性 # 链式比较 1 < 2 < 3 # true(Julia 支持!) # 近似相等(浮点) isapprox(0.1 + 0.2, 0.3) # true 0.1 + 0.2 ≈ 0.3 # 用 ≈ 符号
3. 逻辑运算符
true && false # false(与,短路)
true || false # true(或,短路)
!true # false(非)
# 短路求值
x = 0
x != 0 && println("非零") # 不执行
x == 0 || println("是零") # 执行
4. 位运算符
6 & 3 # 2(与) 6 | 3 # 7(或) 6 ⊻ 3 # 5(异或,输入 \xor Tab) ~6 # -7(取反) 6 << 1 # 12(左移) 6 >> 1 # 3(右移)
5. 集合运算符
[1,2,3] ∪ [2,4] # [1,2,3,4] 并集 \cup [1,2,3] ∩ [2,4] # [2] 交集 \cap [1,2] ⊆ [1,2,3] # true 子集 \subseteq [3,1,2] == [1,2,3] # true(无序)
Julia 数学函数
Julia 数学函数
1. 基本数学函数
abs(-5) # 5 abs2(3) # 9(平方) sqrt(16) # 4.0 cbrt(27) # 3.0(立方根) exp(1) # 2.718281828459045 log(exp(1)) # 1.0 log2(8) # 3.0 log10(100) # 2.0 sign(-9) # -1 clamp(15, 0, 10) # 10(限制范围) min(3, 7, 2) # 2 max(3, 7, 2) # 7
2. 三角函数
sin(π/2) # 1.0 cos(0) # 1.0 tan(π/4) # 0.9999999999999999 # 反三角函数 asin(1.0) # 1.5707963267948966 (π/2) atan(1.0) # 0.7853981633974483 # 双曲函数 sinh(1.0), cosh(1.0), tanh(1.0) # 角度与弧度 sind(90) # 1.0(角度制) rad2deg(π) # 180.0 deg2rad(180) # 3.14159
3. 舍入函数
round(3.7) # 4.0 round(3.2) # 3.0 round(3.5) # 4.0(银行家舍入,偶数为准) floor(3.7) # 3.0 ceil(3.2) # 4.0 trunc(3.7) # 3.0(截断) round(3.14159, digits=2) # 3.14
4. 统计函数
using Statistics data = [1, 3, 5, 7, 9] mean(data) # 5.0 median(data) # 5.0 std(data) # 3.1622776601683795(标准差) var(data) # 10.0(方差) extrema(data) # (1, 9)(最大最小值)
5. 特殊函数
using SpecialFunctions gamma(5) # 24.0(Γ函数,4!) beta(2, 3) # 0.08333333333333333 erf(0.0) # 0.0(误差函数)
Julia 字符串
Julia 字符串
1. 创建字符串
s1 = "hello" s2 = "含 Unicode: 你好, 世界" s3 = "\"转义\" \\n 换行" # 原始字符串(raw) s4 = raw"路径 C:\users\julia" # 不会处理转义符 # 多行字符串 s5 = """ 第一行 第二行 """
2. 字符串插值
name = "Julia"
version = 1.10
println("欢迎使用 $name v$version")
println("计算: $(2 + 3)")
println("长度: $(length(name))")
# 特殊字符插值
println("变量名: $($name)")
3. 索引与切片
s = "Julia语言" s[1] # 'J' s[end] # '言'(按字符索引) s[1:5] # "Julia" # 注意:UTF-8 字节索引,多字节字符不能按字节切 # 字符数组 collect(s) # ['J','u','l','i','a','语','言']
4. 常用方法
s = "Hello, Julia"
length(s) # 13
uppercase(s) # HELLO, JULIA
lowercase(s) # hello, julia
replace(s, "Julia" => "World")
startswith(s, "Hello") # true
endswith(s, "Julia") # true
occursin("llo", s) # true
split(s, ", ") # ["Hello", "Julia"]
join(["a","b"], "-") # "a-b"
strip(" hi ") # "hi"
repeat("ab", 3) # "ababab"
s[findfirst("Julia", s)] # 查找位置
5. 正则配合
m = match(r"\d+", "年龄: 25") m.match # "25" # 捕获组 m2 = match(r"(\w+)@(\w+)", "user@example.com") m2.captures # ["user", "example"]
Julia 正则表达式
Julia 正则表达式
1. 创建正则
# r"..." 创建正则对象 r1 = r"\d+" # 数字 r2 = r"^[A-Z]+$" # 大写字母 r3 = r"(?i)julia" # 忽略大小写 # 编译标志 r4 = r"abc"i # 不区分大小写 r5 = r"abc"m # 多行模式
2. 匹配函数
text = "The price is 99 dollars" # 是否匹配 occursin(r"\d+", text) # true # 首次匹配 m = match(r"(\w+) is (\d+)", text) m.match # "price is 99" m.captures # ["price", "99"] m[1] # "price" # 全部匹配 collect(eachmatch(r"\w+", text)) # 所有单词 # 匹配位置 m.offset # 起始索引
3. 替换与分割
text = "2026-08-18"
# 替换
replace(text, r"-" => "/") # "2026/08/18"
replace("a1b2c3", r"\d" => "x") # "axbxcx"
# 分割
split("1,2,3,4", r",") # ["1","2","3","4"]
split("a b c", r"\s+") # ["a","b","c"]
4. 常用模式
r"\d+" # 数字
r"\w+" # 单词字符
r"\s" # 空白
r"." # 任意字符(除换行)
r"[a-z0-9]" # 字符类
r"^..." # 行首
r"...$" # 行尾
r"a{2,4}" # a 出现 2-4 次
r"(ab|cd)" # 分组或
r"\d{3}-\d{4}" # 电话格式 123-4567
5. 验证邮箱示例
email_pattern = r"^[\w.-]+@[\w.-]+\.[A-Za-z]{2,}$"
function valid_email(s)
return occursin(email_pattern, s)
end
println(valid_email("user@example.com")) # true
println(valid_email("bad@@email")) # false
Julia 函数
Julia 函数
1. 函数定义
# 传统形式
function add(a, b)
return a + b
end
# 单行形式
sub(a, b) = a - b
# 无需 return,最后一个表达式即返回值
function square(x)
x * x
end
println(add(2, 3)) # 5
println(sub(10, 4)) # 6
println(square(5)) # 25
2. 参数特性
# 默认参数
function greet(name, greeting="Hello")
"$greeting, $name!"
end
greet("Julia") # Hello, Julia!
greet("Julia", "Hi") # Hi, Julia!
# 关键字参数
function config(; host="localhost", port=8080)
"连接 $host:$port"
end
config() # localhost:8080
config(port=9090) # localhost:9090
config(host="api", port=80) # api:80
# 可变参数
function sum_all(nums...)
sum(nums)
end
sum_all(1, 2, 3, 4) # 10
3. 匿名函数
f = x -> x^2 f(5) # 25 # 多参数 g = (x, y) -> x + y g(1, 2) # 3 # 配合 map/filter map(x -> x^2, [1,2,3]) # [1,4,9] filter(x -> x % 2 == 0, [1,2,3,4]) # [2,4] reduce(+, [1,2,3,4]) # 10
4. 多分派
# 同一函数名,不同参数类型 area(r::Float64) = π * r^2 area(r::Int) = "整数半径: $(π * r^2)" area(2.0) # 调用 Float64 版本 area(2) # 调用 Int 版本
5. 函数组合与管道
# 管道操作符 [1,2,3] |> sum |> println # 6 # 组合 h = sqrt ∘ abs # \circ 组合 h(-16) # 4.0
Julia 流程控制
Julia 流程控制
1. if-elseif-else
score = 85
if score >= 90
println("优秀")
elseif score >= 80
println("良好")
elseif score >= 60
println("及格")
else
println("不及格")
end
# if 是表达式,可赋值
grade = if score >= 90 "A"
elseif score >= 80 "B"
else "C" end
2. 三元运算符
x = 10 result = x > 0 ? "正数" : "非正数" println(result) # 正数
3. for 循环
# 区间
for i in 1:5
print(i, " ")
end # 1 2 3 4 5
# 数组
for x in [10, 20, 30]
println(x)
end
# 嵌套循环
for i in 1:3, j in 1:3
print("($i,$j) ")
end
# 步长
for i in 1:2:9 # 1,3,5,7,9
println(i)
end
# 倒序
for i in 5:-1:1
println(i)
end
4. while 循环
i = 0
while i < 5
global i += 1
println(i)
end
5. break/continue/return
for i in 1:10
if i == 3
continue # 跳过
elseif i == 8
break # 退出
end
println(i)
end
# 嵌套循环标签
for i in 1:3
for j in 1:3
if j == 2
break # 只跳出内层
end
end
end
Julia 字典和集合
Julia 字典和集合
1. 字典(Dictionary)
# 创建字典
d1 = Dict("a" => 1, "b" => 2)
d2 = Dict{String, Int}() # 空字典
# 访问
d1["a"] # 1
get(d1, "c", 0) # 0(带默认值)
haskey(d1, "a") # true
# 修改与添加
d1["c"] = 3
d1["a"] = 100
# 删除
delete!(d1, "b")
# 键值对数组
pairs(d1) # 迭代键值对
keys(d1) # 所有键
values(d1) # 所有值
length(d1) # 长度
2. 遍历字典
d = Dict("name" => "Julia", "type" => "language")
for (k, v) in d
println("$k => $v")
end
for k in keys(d)
println(k)
end
3. 集合(Set)
# 创建集合(无序,无重复)
s1 = Set([1, 2, 3, 3, 2])
# 结果为 Set([1, 2, 3])
# 添加/删除
push!(s1, 4)
delete!(s1, 1)
in(4, s1) # true
# 集合运算
a = Set([1, 2, 3])
b = Set([3, 4, 5])
union(a, b) # 并集 {1,2,3,4,5}
intersect(a, b) # 交集 {3}
setdiff(a, b) # 差集 {1,2}
issubset(a, Set([1,2,3,4])) # true
4. 命名元组字典转换
nt = (name="Julia", ver=1.10) d = Dict(pairs(nt)) # 命名元组 → 字典 d[:name] # 或 d["name"]
Julia 日期和时间
Julia 日期和时间
1. 获取当前时间
using Dates now() # 当前日期时间 today() # 当前日期 time() # Unix 时间戳(秒) datetime2unix(now()) # 转时间戳
2. 创建日期
d1 = Date(2026, 8, 18)
d2 = Date("2026-08-18") # 字符串解析
d3 = DateTime(2026, 8, 18, 15, 30, 0)
d4 = DateTime("2026-08-18T15:30:00")
year(d1) # 2026
month(d1) # 8
day(d1) # 18
dayofweek(d1) # 2(星期几,周一=1)
dayname(d1) # "Tuesday"
monthname(d1) # "August"
dayofyear(d1) # 230
3. 日期运算
d1 = Date(2026, 1, 1) d2 = Date(2026, 12, 31) d2 - d1 # 364 days d1 + Day(30) # 加30天 d1 + Month(3) # 加3个月 d1 + Year(1) # 加1年 d1 - Week(2) # 减2周 # 比较 d1 < d2 # true Dates.value(d2 - d1) # 364
4. 格式化输出
dt = DateTime(2026, 8, 18, 15, 30) # 自定义格式 Dates.format(dt, "yyyy-mm-dd HH:MM:SS") # "2026-08-18 15:30:00" Dates.format(dt, "yyyy年mm月dd日") # "2026年08月18日" Dates.format(dt, "HH:MM") # 解析 parse(Date, "2026/08/18", dateformat"yyyy/mm/dd")
5. 时间间隔
elapsed = Dates.now() - DateTime(2026, 1, 1) Dates.value(elapsed) # 毫秒数 # 工作日 isweekend(Date(2026, 8, 22)) # true(周六) Dates.dayofweek(Dates.today())
Julia 文件读写
Julia 文件读写
1. 写文件
# 写入(覆盖)
open("data.txt", "w") do io
write(io, "第一行\n")
write(io, "第二行\n")
end
# 追加
open("data.txt", "a") do io
write(io, "追加内容\n")
end
# 简便写法
write("data2.txt", "hello julia")
# 写入多行数组
lines = ["a", "b", "c"]
open("data3.txt", "w") do io
for l in lines
println(io, l)
end
end
2. 读文件
# 读取全部内容
content = read("data.txt", String)
# 逐行读取
open("data.txt") do io
for line in eachline(io)
println(line)
end
end
# 读取为字节
bytes = read("data.txt")
# 简便方式
readlines("data.txt") # ["第一行", "第二行"]
3. 文件操作
isfile("data.txt") # true
isdir("data.txt") # false
filesize("data.txt") # 字节数
# 目录操作
mkdir("mydir")
isdir("mydir") # true
rm("mydir"; recursive=true) # 删除目录
cp("data.txt", "copy.txt") # 复制
mv("copy.txt", "rename.txt") # 移动/重命名
# 列出目录
readdir(".") # 当前目录所有文件
4. CSV 读写
using CSV, DataFrames
# 写 CSV
df = DataFrame(name=["A", "B"], score=[90, 85])
CSV.write("scores.csv", df)
# 读 CSV
df2 = CSV.read("scores.csv", DataFrame)
println(df2)
Julia 元编程
Julia 元编程
元编程是 Julia 的杀手锏:代码可以生成代码,宏在编译期转换表达式,这是高性能科学计算框架的基础。
1. 表达式(Expr)
# 引用表达式 ex = :(a + b) typeof(ex) # Expr ex.head # :call ex.args # [:+, :a, :b] # 构建表达式 ex2 = Expr(:call, :+, 1, 2) eval(ex2) # 3(执行表达式)
2. 字符串转表达式
ex3 = Meta.parse("x * 2 + 1")
eval(Expr(:call, :(x->x^2), 5)) # 25
3. 定义宏
# 宏定义:接收表达式,返回新表达式
macro shout(s)
return :(uppercase(string($s)))
end
println(@shout "hello") # HELLO
# 宏调用 @shout "hello"
# 带参数宏
macro add_tag(x)
return :(println("标签: ", $x))
end
@add_tag "测试"
4. 宏的调试
# 查看宏展开结果
@macroexpand @shout "hi"
# :(uppercase(string("hi")))
# 调试宏
macro my_if(cond, then_branch)
return quote
if $cond
$then_branch
end
end
end
5. 内置常用宏
@time println("计时") # 显示执行时间
@show 1 + 1 # 显示表达式和结果
@assert 1 == 1 # 断言
@printf("值 %.2f\n", 3.14) # 格式化
@vectorize_1arg # 旧版向量化
@eval 1 + 1 # 立即求值
6. 元编程应用
# 批量生成函数
for op in [:+, :-, :*]
@eval function apply_$op(a, b)
return $op(a, b)
end
end
apply_+(3, 4) # 7
apply_*(3, 4) # 12
# 生成结构定义
macro gen_struct(name, fields...)
return quote
struct $name
$(fields...)
end
end
end
@gen_struct Point x y
p = Point(1, 2)
第 1 / 18 节