Julia 函数

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类型检查

十六、小练习(立即上手)

  1. 写函数 fib(n) 计算斐波那契数(递归 + 尾递归)
  2. 实现 map(f, arr) 自定义版本
  3. curry(f, a)(b) 柯里化函数
  4. 用闭包实现计数器
  5. @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 函数性能

随时告诉我!

文章已创建 2305

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部