Julia 函数完全指南(中文版)
“函数是 Julia 的灵魂” —— 多重派发 + 泛型 + 高性能
一、函数基础
1. 定义函数的两种语法
# 标准写法
function add(x, y)
return x + y
end
# 简洁写法(单表达式)
add(x, y) = x + y
# 匿名函数
f = x -> x^2
2. 调用函数
add(3, 4) # 7
f(5) # 25
二、函数参数
1. 位置参数(Positional Arguments)
function greet(name, age)
println("Hello $name, you are $age years old.")
end
greet("Alice", 25)
2. 可选参数(Optional Arguments)—— 默认值
function power(x, n=2)
x^n
end
power(3) # 9
power(3, 3) # 27
3. 关键字参数(Keyword Arguments)—— 命名传递
function plot(x; title="Plot", color=:blue, linewidth=2)
# ...
end
plot(data; title="Sine", color=:red)
位置参数在前,关键字参数在后,用
;分隔
4. 可变参数(Varargs)...
function sum_all(nums...)
sum(nums)
end
sum_all(1, 2, 3, 4) # 10
sum_all(1:10...) # 55
5. 参数解构(Destructuring)
function point_info((x, y))
println("Point at ($x, $y)")
end
point_info((3, 4))
三、多重派发(Multiple Dispatch)—— Julia 核心!
同一函数名,不同参数类型 → 不同实现
greet(x::String) = println("Hello, $x!")
greet(x::Int) = println("Number: $x")
greet("Julia") # Hello, Julia!
greet(42) # Number: 42
查看方法表
methods(+) # 显示所有 + 的实现(数百个!)
@which sin(3.14) # 查看具体调用了哪个方法
四、返回值
# 显式返回
function add(x, y)
return x + y
end
# 隐式返回(最后一行)
function add(x, y)
x + y
end
# 多返回值(返回元组)
function stats(arr)
return minimum(arr), maximum(arr), mean(arr)
end
min_val, max_val, avg = stats([1,2,3,4,5])
五、函数是“头等公民”(First-class Functions)
# 赋值给变量
f = sin
f(π/2) # 1.0
# 作为参数传递
map(x -> x^2, [1,2,3]) # [1, 4, 9]
# 高阶函数
function apply_twice(f, x)
f(f(x))
end
apply_twice(sqrt, 16) # 2.0
六、广播(Broadcasting)—— . 语法糖
f(x) = x^2 + 2x + 1
x = [1, 2, 3]
f.(x) # [4, 9, 16] → 逐元素调用
等价于:
broadcast(f, x)
七、管道运算符 |> —— 函数链式调用
# 传统
round(sqrt(abs(-5.5)))
# 管道(更清晰)
-5.5 |> abs |> sqrt |> round
八、匿名函数(Lambda)
x -> x^2
(x, y) -> x + y
((x, y)...) -> x * y # 接收可变参数
filter(x -> x > 0, [-1, 0, 1, 2]) # [1, 2]
九、函数作用域
| 关键字 | 作用域 |
|---|---|
global | 全局变量 |
local | 局部变量(循环、函数内) |
const | 常量(类型可变,值不可变) |
function counter()
local count = 0
() -> count += 1 # 闭包
end
c = counter()
c() # 1
c() # 2
十、闭包(Closure)
function make_adder(n)
x -> x + n
end
add5 = make_adder(5)
add5(10) # 15
十一、函数性能优化
1. 类型稳定(Type Stability)
# 好:返回类型一致
function sum_pos(v::Vector{Int})
s = 0
for x in v
x > 0 && (s += x)
end
return s
end
# 坏:返回类型不确定
bad(x) = x > 0 ? x : "negative"
检查:
@code_warntype f(args)
2. 内联函数 @inline
@inline fast_add(x, y) = x + y
3. 避免全局变量
# 慢
global_rate = 0.1
# 快
function apply_tax(price, rate=0.1)
price * (1 + rate)
end
十二、宏与函数区别
| 特性 | 函数 | 宏 |
|---|---|---|
| 执行时机 | 运行时 | 编译时 |
| 参数求值 | 是 | 否(表达式) |
| 性能 | 快 | 更快(无调用开销) |
| 调试 | 易 | 难 |
@time sleep(1) # 宏
time(() -> sleep(1))() # 函数
十三、综合示例:数值微分
# 中心差分
function derivative(f, x; h=1e-8)
(f(x + h) - f(x - h)) / (2h)
end
f(x) = x^3 - 2x + 1
derivative(f, 1.0) # ≈ 1.0(解析解:3x²-2)
十四、综合示例:高阶函数工厂
function polynomial(coeffs)
n = length(coeffs) - 1
x -> sum(c * x^(n-i) for (i,c) in enumerate(coeffs))
end
p = polynomial([1, 0, -2, 1]) # x³ - 2x + 1
p(1) # 0
十五、函数速查表
| 语法 | 含义 |
|---|---|
f(x) | 调用 |
f(x) = ... | 定义 |
f(x::T) | 类型约束 |
f(x...) | 可变参数 |
f(x; k=v) | 关键字参数 |
f.(x) | 广播 |
x |> f | 管道 |
x -> expr | 匿名函数 |
@inline | 内联 |
@code_warntype | 类型检查 |
十六、小练习(立即上手)
- 写函数
fib(n)计算斐波那契数(递归 + 尾递归) - 实现
map(f, arr)自定义版本 - 写
curry(f, a)(b)柯里化函数 - 用闭包实现计数器
- 写
@timer宏,自动计时函数
答案示例
# 1. 斐波那契
fib_recursive(n) = n <= 1 ? n : fib_recursive(n-1) + fib_recursive(n-2)
fib_tail(n, a=0, b=1) = n == 0 ? a : fib_tail(n-1, b, a+b)
# 2. 自定义 map
mymap(f, arr) = [f(x) for x in arr]
# 3. 柯里化
curry(f, a) = b -> f(a, b)
add = (x,y) -> x+y
add3 = curry(add, 3)
add3(5) # 8
# 4. 计数器
function make_counter()
count = 0
() -> (count += 1)
end
# 5. 计时宏
macro timer(expr)
quote
t = @elapsed $(esc(expr))
println("Time: $t seconds")
$(esc(expr))
end
end
@timer sleep(1)
十七、调试与工具
@which sin(3.14) # 查看方法
@code_lowered f(x) # 低级代码
@code_typed f(x) # 类型推断
@code_llvm f(x) # LLVM IR
@code_native f(x) # 汇编
恭喜!你已精通 Julia 函数!
现在你可以:
- 写出类型安全、高性能的函数
- 用多重派发构建优雅 API
- 用高阶函数写简洁代码
- 实现领域特定语言(DSL)
下一站推荐
| 主题 | 为什么学 |
|---|---|
结构体 struct | 自定义类型 |
| 泛型编程 | Vector{T} |
元编程 @macro | 代码生成 |
| 包开发 | Project.toml |
| 并行计算 | @threads, Distributed |
需要我:
- 写一个 数学函数库(支持任意精度)?
- 实现 自动微分(前向模式)?
- 构建 DSL(如 SQL 查询生成器)?
- 对比 Julia vs Python 函数性能?
随时告诉我!