NetLogo动态变量定义求助:通过CSV加载变量名失败
动态定义NetLogo海龟变量的问题解决
NetLogo里用run动态执行let命令时存在作用域限制——run内部创建的局部变量仅在该run的临时作用域内有效,执行完毕后就会被销毁,这就是你代码报错的核心原因。
可正常运行的代码分析
这段代码能正常工作,是因为你显式在当前海龟的作用域里用let ID "123"定义了局部变量,后续run执行的set ID ...能找到这个已存在的变量:
create-turtles 1 [ let attribute-name item 0 attributes set var attribute-name let ID "123" ; attribute-name 为 ID,提前在当前作用域定义变量 let attribute-value item 0 data run (word "set " attribute-name " " attribute-value) ]
无法运行的代码问题根源
下面这段代码里,run (word "let " var " " 123)确实会解析成let ID 123,但这个ID变量只存在于run命令的临时执行环境中,run结束后变量就被销毁了,所以后续set ID ...会提示变量未定义:
create-turtles 1 [ let attribute-name item 0 attributes set var attribute-name run (word "let " var " " 123) ; 变量仅在run的临时作用域内有效 let attribute-value item 0 data run (word "set " attribute-name " " attribute-value) ; 找不到已销毁的ID变量 ]
可行解决方法
NetLogo不支持动态创建局部变量(let的变量名必须在编写代码时确定),你可以根据需求选择下面两种方案:
方案1:提前声明所有海龟变量
如果CSV里的属性名是固定集合,在代码开头用turtles-own显式声明所有需要的海龟变量,之后就能用run动态赋值:
; 代码开头声明海龟变量 turtles-own [ID age gender] ; 创建海龟时的代码 create-turtles 1 [ let attribute-name item 0 attributes let attribute-value item 0 data run (word "set " attribute-name " " attribute-value) ]
方案2:用字典存储动态属性
如果属性名完全不确定,推荐用一个海龟变量存储字典,把CSV里的属性名和值都存在字典中,不需要动态创建变量:
; 声明存储属性的海龟变量 turtles-own [attr-dict] ; 创建海龟并加载属性 create-turtles 1 [ set attr-dict make-dictionary ; 遍历attributes和data的对应元素 foreach attributes data [ [attr val] -> dict-set attr-dict attr val ] ; 后续访问属性示例:获取ID的值 print dict-get attr-dict "ID" ]
内容的提问来源于stack exchange,提问作者KaM
相关产品推荐
相关产品推荐

