Skip to content

函数作用域

局部变量

定义局部变量

bash
#!/bin/bash

# 定义函数
func() {
    local local_var="局部变量"
    echo "函数内: $local_var"
}

# 调用函数
func

# 尝试访问局部变量
echo "函数外: $local_var"  # 输出空行

局部变量 vs 全局变量

bash
#!/bin/bash

# 全局变量
global_var="全局变量"

# 定义函数
func() {
    local local_var="局部变量"
    echo "函数内 - 全局变量: $global_var"
    echo "函数内 - 局部变量: $local_var"
}

# 调用函数
func

# 访问变量
echo "函数外 - 全局变量: $global_var"
echo "函数外 - 局部变量: $local_var"  # 输出空行

全局变量

定义全局变量

bash
#!/bin/bash

# 定义函数
func() {
    global_var="全局变量"
    echo "函数内: $global_var"
}

# 调用函数
func

# 访问全局变量
echo "函数外: $global_var"

修改全局变量

bash
#!/bin/bash

# 全局变量
count=0

# 定义函数
increment() {
    count=$((count + 1))
    echo "函数内: $count"
}

# 调用函数
increment
echo "函数外: $count"

increment
echo "函数外: $count"

变量遮蔽

局部变量遮蔽全局变量

bash
#!/bin/bash

# 全局变量
var="全局变量"

# 定义函数
func() {
    local var="局部变量"
    echo "函数内: $var"
}

# 调用函数
func

# 访问全局变量
echo "函数外: $var"

嵌套函数中的变量遮蔽

bash
#!/bin/bash

# 全局变量
var="全局变量"

# 定义外部函数
outer() {
    local var="外部变量"
    echo "外部函数: $var"
    
    # 定义内部函数
    inner() {
        local var="内部变量"
        echo "内部函数: $var"
    }
    
    # 调用内部函数
    inner
    echo "外部函数: $var"
}

# 调用外部函数
outer

# 访问全局变量
echo "全局: $var"

函数返回值

使用 echo 返回值

bash
#!/bin/bash

# 定义函数
get_value() {
    echo "返回值"
}

# 调用函数并获取返回值
result=$(get_value)
echo "返回值: $result"

使用 return 返回状态码

bash
#!/bin/bash

# 定义函数
check_value() {
    if [ $1 -gt 0 ]; then
        return 0  # 成功
    else
        return 1  # 失败
    fi
}

# 调用函数
check_value 10
if [ $? -eq 0 ]; then
    echo "值大于 0"
else
    echo "值不大于 0"
fi

同时返回值和状态码

bash
#!/bin/bash

# 定义函数
divide() {
    if [ $2 -eq 0 ]; then
        echo "错误: 除数不能为 0"
        return 1
    fi
    echo $(($1 / $2))
    return 0
}

# 调用函数
result=$(divide 10 2)
status=$?

if [ $status -eq 0 ]; then
    echo "结果: $result"
else
    echo "$result"
fi

静态变量

模拟静态变量

bash
#!/bin/bash

# 定义函数
counter() {
    local __counter_var="__counter_$FUNCNAME"
    if [ -z "${!__counter_var}" ]; then
        eval "$__counter_var=0"
    fi
    eval "$__counter_var=\$((\${$__counter_var} + 1))"
    eval "echo \$($__counter_var)"
}

# 调用函数
counter  # 输出:1
counter  # 输出:2
counter  # 输出:3

闭包

模拟闭包

bash
#!/bin/bash

# 创建闭包
make_counter() {
    local count=0
    echo "$count"
}

# 使用闭包
count=$(make_counter)
echo "计数: $count"

实用示例

示例1:计数器

bash
#!/bin/bash

# 全局计数器
count=0

# 增加计数
increment() {
    count=$((count + 1))
    echo $count
}

# 减少计数
decrement() {
    count=$((count - 1))
    echo $count
}

# 重置计数
reset() {
    count=0
    echo $count
}

# 使用函数
increment  # 输出:1
increment  # 输出:2
decrement  # 输出:1
reset      # 输出:0

示例2:配置管理

bash
#!/bin/bash

# 全局配置
config_file="/etc/config.conf"
log_dir="/var/log"
max_size=100

# 设置配置
set_config() {
    config_file="$1"
    log_dir="$2"
    max_size="$3"
}

# 获取配置
get_config() {
    echo "配置文件: $config_file"
    echo "日志目录: $log_dir"
    echo "最大大小: $max_size"
}

# 使用函数
set_config "/new/config.conf" "/new/log" 200
get_config

示例3:缓存

bash
#!/bin/bash

# 缓存数组
declare -A cache

# 设置缓存
set_cache() {
    local key="$1"
    local value="$2"
    cache["$key"]="$value"
}

# 获取缓存
get_cache() {
    local key="$1"
    if [ -n "${cache[$key]}" ]; then
        echo "${cache[$key]}"
        return 0
    else
        return 1
    fi
}

# 使用函数
set_cache "user1" "张三"
set_cache "user2" "李四"

if get_cache "user1"; then
    echo "缓存命中: $?"
else
    echo "缓存未命中"
fi

示例4:作用域隔离

bash
#!/bin/bash

# 全局变量
global_var="全局变量"

# 定义函数
func() {
    local local_var="局部变量"
    
    echo "=== 函数内 ==="
    echo "全局变量: $global_var"
    echo "局部变量: $local_var"
    
    # 修改全局变量
    global_var="修改后的全局变量"
    
    # 定义嵌套函数
    nested_func() {
        local nested_var="嵌套变量"
        
        echo "=== 嵌套函数内 ==="
        echo "全局变量: $global_var"
        echo "局部变量: $local_var"
        echo "嵌套变量: $nested_var"
    }
    
    # 调用嵌套函数
    nested_func
    
    echo "=== 函数内 ==="
    echo "全局变量: $global_var"
    echo "局部变量: $local_var"
}

# 调用函数
func

echo "=== 函数外 ==="
echo "全局变量: $global_var"
echo "局部变量: $local_var"  # 输出空行
echo "嵌套变量: $nested_var"  # 输出空行

最佳实践

1. 使用局部变量

bash
# 好的做法
func() {
    local var="局部变量"
    echo "$var"
}

# 不好的做法
func() {
    var="局部变量"
    echo "$var"
}

2. 避免全局变量

bash
# 好的做法
func() {
    local var="局部变量"
    echo "$var"
}

# 不好的做法
var="全局变量"

func() {
    var="修改后的全局变量"
    echo "$var"
}

3. 明确变量作用域

bash
# 好的做法
func() {
    local local_var="局部变量"
    global_var="全局变量"
    echo "$local_var"
    echo "$global_var"
}

# 不好的做法
func() {
    var="变量"
    echo "$var"
}

总结

函数作用域的关键点:

  1. 局部变量:使用 local 关键字定义
  2. 全局变量:在函数外定义的变量
  3. 变量遮蔽:局部变量遮蔽全局变量
  4. 函数返回值:使用 echo 返回值,使用 return 返回状态码
  5. 静态变量:使用特殊技巧模拟静态变量
  6. 闭包:使用函数和变量模拟闭包
  7. 最佳实践:使用局部变量,避免全局变量,明确变量作用域

下一节我们将学习函数库的使用。