2015-04-16 65 views
3

我有一個變量「名稱」,其值是另一個變量的名稱。 因此,例如:球拍:獲取名稱變量的值存儲在另一個變量中

(define name 'a) 
(define a 1) 

那麼我會希望做這樣的事情:

(set! ,name 10) 

但是這引起了一個錯誤,所以我想那個「名」是通過它的替換價值(即'a)。因此,上面的代碼將變量「a」的值設置爲10,並且「name」變量保持不變。

我知道我能做到這一點是這樣的:

(eval `(set! ,name 10)) 

但是這僅適用如果包含在「名稱」變量是一個全局變量,這是不是在我的程序的情況。

目前我通過引入新的命名空間解決了這個問題,但是這使得代碼有點難看,這就是爲什麼我會避免使用eval(從而也避免引入新的命名空間)。

如果我沒有弄錯我在C++中,這將提領的句柄(指針的指針)來完成。

回答

3

之所以(eval `(set! ,name 10))不起作用,是局部變量的名字都沒有出現在運行時。局部變量存儲在堆棧中,因此對局部變量的引用和賦值被編譯爲「獲取第i個變量中的值(從棧頂開始計數)」並「將該值存儲在第i個槽中堆棧「。然而

模塊級變量都存儲在一個命名空間,所以你可以使用他們的eval解決方案。

那麼如何處理局部變量?或許,這將是最好使用哈希表來代替,但如果你真的需要它,做這樣的事情:

(define (set-local-variable name val) 
    (match name 
    ['a (set! a val)] 
    ['b (set! b val)] 
    ...)) 

其中a,b,...是局部變量。您當然需要將定義放在所討論的局部變量的範圍內。這也意味着您需要爲每個範圍定義一個set-local-variable

這很快成爲維持疼痛,因此尋找一種替代解決方案 - 例如,一個基於哈希表。

+0

是的,但實際上它不是我想要的。我的程序有一部分在我的電腦上運行,另一部分在芯片上運行。我在我的電腦上維護着一個「世界」,所以我可以很容易地要求它被更新。這樣做我只發送通過TCP/IP更改的數據,更新後我不必再發送TCP/IP消息。所以在我的電腦上,我收到例如'(速度5)。知道變量在我的電腦上有相同的名稱我不想檢查每個可能的變量名稱。我只想做:(set!receivedName receivedValue)。而不是對每個可能的變量名稱進行大的條件檢查。 – HyperZ

+0

這就是爲什麼我建議使用哈希表代替。 (我說這是不可能做出基於評估的解決方案)。 – soegaard

+0

對不起,如果我誤解了你。但我真的不知道如何使用散列表來實現。 – HyperZ

相關問題