私はGCLを使用してUbuntuでプログラミングしています。さまざまなソースからのCommonLispに関するドキュメントから、ローカル変数をlet
作成し、既存の変数の値を設定することを理解しています。以下の場合、2つの変数を作成し、それらの値を合計する必要があります。setq
setq
(defun add_using_setq ()
(setq a 3) ; a never existed before , but still I'm able to assign value, what is its scope?
(setq b 4) ; b never existed before, but still I'm able to assign value, what is its scope?
(+ a b))
let
(defun add_using_let ( )
(let ((x 3) (y 4)) ; creating variables x and y
(+ x y)))
どちらの場合も、私は同じ結果を達成しているようです。使用setq
とlet
ここの違いは何ですか?使用するsetq
必要のあるすべての場所で(構文的に簡単なため)使用できないのはなぜlet
ですか?
setq
変数に値を割り当てますが、let
新しい変数/バインディングを導入します。たとえば、何が起こるか見てください
(let ((x 3))
(print x) ; a
(let ((x 89))
(print x) ; b
(setq x 73)
(print x)) ; c
(print x)) ; d
3 ; a
89 ; b
73 ; c
3 ; d
外側let
はローカル変数を作成しx
、内側let
は内側の変数をシャドウイングする別のローカル変数を作成します。let
変数をシャドウイングするために使用しても、シャドウイングされた変数の値には影響しないことに注意してください。x
ライン内をd
れるx
アウターによって導入されlet
、その値は変更されていません。setq
呼び出される変数にのみ影響します。この例はsetq
、ローカル変数で使用されることを示していますが、特別な変数(つまり、動的にスコープされ、通常はdefparameter
またはdefvar
:で定義される)で使用することもできます。
CL-USER> (defparameter *foo* 34)
*FOO*
CL-USER> (setq *foo* 93)
93
CL-USER> *foo*
93
注setq
(移植性)はありません作成した変数を、一方でlet
、defvar
、defparameter
、&C。行う。setq
(まだ)変数ではない引数で呼び出されたときの動作は定義されておらず、何をするかを決定するのは実装次第です。たとえば、SBCLは大声で不平を言います:
CL-USER> (setq new-x 89)
; in: SETQ NEW-X
; (SETQ NEW-X 89)
;
; caught WARNING:
; undefined variable: NEW-X
;
; compilation unit finished
; Undefined variable:
; NEW-X
; caught 1 WARNING condition
89
もちろん、これらの概念をよりよく理解するための最良の方法は、より多くのLispコード(時間とともに付属)を読み書きし、HyperSpecのエントリを読み取り、相互参照、特に用語集のエントリに従うことです。例えば、HyperSpecからの短い説明のためsetq
とlet
、次のとおりです。
変数とバインディングについてもっと読みたいと思うかもしれません。let
そしてlet*
また動的変数として、いくつかの特殊な動作持ってspecial
宣言を(しかし、あなたはおそらくしばらくの間、それについて知っておく必要はありません)、および特定のケースでは(おそらくしばらくについて知る必要がないということ)する場合、変数は実際には変数ではなく、実際にsetq
はと同等setf
です。HyperSpecに詳細があります。
Stack Overflowには、まったく重複していない質問がいくつかありますが、それでも、CommonLispで使用できるさまざまな変数定義および代入演算子の使用法を理解するのに役立つ場合があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加