배열의 목록을 여기에 혼동스럽게합니다.
tcl에서는 배열을 함수로 전달하거나 함수에서 반환 할 수 없습니다. 또한 tcl은 C++이 "맵"이라고 부르는 Perl과 Ruby의 "해시"또는 Javascript가 "객체"라고 부르는 것에 대해 "배열"이라는 용어를 사용합니다. 이 모든 것은 일반적으로 컴퓨터 과학에서 "연관 배열 (associative arrays)"로 알려져있다. 따라서 tcl의 "배열"은 데이터의 순서가 아니라 키 - 값 쌍입니다.
배열은 일반적으로 값으로 변하지 않습니다 (또는 숙련 된 tcl 프로그래머가 "문자열"이라고 부르는 것). 따라서이 :
array set tcArrayName {$fileName $tcSpec};
return $tcArrayName;
구문 오류가 발생
can't read "tcArrayName": variable is array
당신은 실제로 당신이 다음 반환 할 수있는 값으로 배열의 내용을 변질 수 있습니다.
"$fileName $tcSpec"
도에 발생 : 위의 명령은 두 가지 요소 목록의 형태로 tcArrayName
배열의 내용을 반환합니다
return [array get tcArrayName]
:하지만 당신은 [array get]
명령을 통해 수동으로해야 끈이어야한다. '$'다음에 'f', 'i', 'l', 'e', 'N', 'a', 'm', 'e'등의 실제 문자열이 있습니다. 파일 이름 및 연결된 항목 이름 및 항목 ID 리터럴 문자열 "$ fileName $ tcSpec". 당신이 코드 줄에 {}
그룹을 사용했기 때문이다
: TCL에서
array set tcArrayName {$fileName $tcSpec}
, {xxx}
는 'xxx'
펄에서와 같은 방식으로 동작합니다. 기본적으로 대체되지 않는 리터럴 문자열입니다.당신은 TCL이 $
대체를하고 싶은 경우에 당신은 ""
그룹 사용해야 :
array set tcArrayName "$fileName $tcSpec"
을하지만 fileName
공백이 포함 된 경우 다음 코드를 깰 때문에이 허약하다.
array set tcArrayName [list $fileName $tcSpec]
그러나 당신이하고있는 모든 또한 더에 dict
로 알려진 키 - 값 목록 (그것을 초기화하기 때문에이 경우에 array
를 사용하여 약간의 중복 :이 작업을 수행하는보다 강력한 방법입니다 tcl의 최신 버전, tcl의 어떤 버전을 사용하고 있습니까?) 즉시 폐기하고 키 - 값 목록으로 컨텐츠를 반환하십시오.
proc B {fileID} {
set fileName [::getFileName $fileID]; # getFileName returns filename from fileid
set tcName "[set ItemName]_[set ItemId]"
return [list $fileName $tcSpec]
}
그러나 우리는 분명히 아직하지 않은 : 단순히 키와 값의 목록을 반환하지 왜
.
can't read "ItemName": no such variable
TCL은 기본적으로 함수로 전역 변수를 가져 오지 않기 때문이다 : 당신이 B
를 실행하려고하면이 오류가 표시됩니다. 따라서 ItemName
및 ItemId
변수는 B
에 없습니다.
proc B {fileID} {
global ItemName
global ItemId
# ...
}
또는 전역 네임 스페이스를 통해 액세스를 정규화 된 변수 이름 사용 :
set tcName "[set ::ItemName]_[set ::ItemId]"
그래서 B
은 다음과 같아야합니다
을 당신은
global
명령을 통해 명시 적으로 가져올 필요 하나
proc B {fileID} {
set fileName [::getFileName $fileID]; # getFileName returns filename from fileid
set tcName "[set ::ItemName]_[set ::ItemId]"
return [list $fileName $tcSpec]
}
그건 B
입니다. 그러나 A
도 처리해야합니다 :
예상대로
proc A {} {
set lst_A [list];
if {true} { ;# assuming that there will be a valid condition here
lappend lst_A [::B $::file1];
} else {
foreach id $allId {
lappend lst_A [::B $id];
}
}
return $lst_A;
}
이 작동합니다 :
can't read "file1": no such variable
우리는 변수 file1
에 액세스 할을 약간 수정해야합니다.
키 - 값 목록을 사용할 때 약간의 속도를 높이려면 dicts
을 읽어야합니다. 즉, dicts는 위에 주어진 코드에 영향을 미치지 않지만 코드 A
에 영향을줍니다. dicts를 사용하려는 경우 위 전화를 dict append
으로 바꿀 수 있습니다. 그러나 이전 버전의 tcl에는 dict이 없습니다.
8.6을 사용하는 경우 다음과 같이 작성할 수 있습니다. if {1} {return [list [B $ :: file1]] else {return [lmap id $ : allId {B $ id }]}}' –
그래도 8.6 대신 lect 대신'dict append'를 사용하여 foreach를 사용하면 dict-list shimmering을 피할 수 있기 때문에 더 좋습니다. – slebetman
위의 문제를 해결해 주셔서 감사합니다. 내 실제 문제를 해결하는 다른 방법을 찾았지만 귀하의 대답은 배열 사용에 대한 훌륭한 설명이었습니다. Slebetman에게 다시 한번 감사드립니다. :) –