Bash中用关联数组模拟类调用函数报错的问题咨询
在Bash中用关联数组模拟类:解决方法调用报错问题
错误原因分析
你遇到的问题核心有两点:
- 若
say_hello是在person函数内部定义的局部函数,当person执行完毕后,局部函数会被销毁,外部自然无法找到 - 直接使用
${john[say_hello]}时,Bash仅会展开变量得到函数名,但不会自动执行该函数,需要用正确的间接调用语法
解决方案一:带实例唯一标识的全局方法
给每个实例的方法添加唯一后缀,避免不同实例的方法冲突,同时保证函数全局可访问:
classes.sh
person() { local name="$1" local age="$2" local instance_id="$3" # 传入实例名作为唯一标识 # 定义带实例标识的全局方法 eval "say_hello_${instance_id}() { echo \"Hello, I'm ${name}, ${age} years old\" }" # 初始化全局关联数组存储属性与方法 declare -gA "$instance_id"=( [name]="$name" [age]="$age" [say_hello]="say_hello_${instance_id}" ) }
main.sh
source classes.sh # 创建实例,第三个参数指定关联数组名称 person "John" 30 john # 正确调用方法:展开变量后执行 "${john[say_hello]}"
解决方案二:用Nameref实现闭包(Bash 4.3+)
通过declare -n(命名引用)绑定实例属性,避免方法名冲突:
classes.sh
person() { local instance_name="$3" # 声明全局关联数组存储属性 declare -gA "$instance_name"=( [name]="$1" [age]="$2" ) # 定义全局方法,用nameref引用实例属性 say_hello() { declare -n self="$1" echo "Hello, I'm ${self[name]}, ${self[age]} years old" } # 将方法与实例绑定后存入数组 eval "$instance_name[say_hello]='say_hello $instance_name'" }
main.sh
source classes.sh person "John" 30 john # 直接执行数组中存储的命令字符串 "${john[say_hello]}"
补充:简化调用的小技巧
如果你不想每次都写引号,也可以用eval触发执行(仅在你能完全控制变量内容时使用,避免安全风险):
eval "${john[say_hello]}"
内容的提问来源于stack exchange,提问作者Cobalt
相关产品推荐
相关产品推荐

