【问题标题】:LISP how to call an object from a variable after taking out the name of the object from another variableLISP如何在从另一个变量中取出对象的名称后从一个变量中调用一个对象
【发布时间】:2015-01-10 15:46:19
【问题描述】:

我还是LISP的初学者,希望大家能给我一些关于如何解决以下问题的建议。

(CG-USER(1):defstruct Test()
        (TestValue  10)
        (TestChild 'none)
        )
TEST

CG-USER(2): (defun testvalue(item)
         (slot-value item 'TESTCHILD))
TESTVALUE

CG-USER(3):(setf TestObject(make-Test :TestChild '(TestObject2 B C)))
#S(TEST :NIL NIL :TESTVALUE 10 :TESTCHILD (TESTOBJECT2 B C))

CG-USER(4): (setf TestObject2(make-Test :TestChild '(D E F)))
#S(TEST :NIL NIL :TESTVALUE 10 :TESTCHILD (D E F))

CG-USER(5): (setf aaa (car (testvalue TestObject)))
TESTOBJECT2

CG-USER(6): (testvalue aaa)
Error: The slot TESTCHILD is missing from the object TESTOBJECT2 of class #<BUILT-IN-CLASS         SYMBOL> during
   operation SLOT-VALUE
[condition type: PROGRAM-ERROR]

以下是我的代码。如您所见,我正在尝试通过函数 testvalue 读取对象 TestObject2 中的详细信息。我的主要目的是能够首先从另一个对象(在本例中为TestObject)确定对象的名称(TestObject2),因为我还不知道名称TestObject2 的名称。

但是,一旦我成功检索到名称 TestObject2 ,当我尝试访问对象内的元素 (TestObject2) 时,它不再识别持有 TestObject2 的变量(在这种情况下,“ aaa") 作为对象。因此,它无法读取它的testvalue,从而导致错误。

我是 LISP 的初学者,我不知道如何解决这个问题。如果有人可以为此提供示例解决方案,那就太好了。谢谢。

P/S:另外,请问这行中的NIL NIL 是什么?有什么办法可以去掉?

#S(TEST :NIL NIL :TESTVALUE 10 :TESTCHILD (D E F))

【问题讨论】:

    标签: object lisp common-lisp


    【解决方案1】:

    第二个问题:

    (defstruct Test()
      (TestValue  10)
      (TestChild 'none))
    

    让我们上面的格式略有不同:

    (defstruct Test        ; the structure has a name `TEST`
      ()                   ; the first slot is named `NIL`
      (TestValue  10)      ; the second slot is named `TESTVALUE`
      (TestChild 'none))   ; the third slot is named `TESTCHILD`
    

    因此,删除第一个插槽是有意义的... ;-) 我们得到:

    (defstruct Test        ; the structure has a name `TEST`
      (TestValue  10)      ; the first slot is named `TESTVALUE`
      (TestChild 'none))   ; the second slot is named `TESTCHILD`
    

    第一个问题

    TESTOBJECT2 是一个符号。如果符号有值,您可以使用函数SYMBOL-VALUE 检索它。

    (symbol-value 'testobject2)
    

    通常你想稍微精简一下你的代码:

    CL-USER 42 > (defstruct test
                   (value  10)
                   (child 'none))
    TEST
    

    在上面我们不需要test 前缀。 DEFSTRUCT 已经创建了以 TEST- 为前缀的访问器。

    CL-USER 43 > (setf test-object (make-test :child '(test-object2 b c)))
    #S(TEST :VALUE 10 :CHILD (TEST-OBJECT2 B C))
    

    请注意,在您的示例和上面的代码中,:child 不是结构。它只是三个符号的列表。

    CL-USER 44 > (setf test-object2 (make-test :child '(d e f)))
    #S(TEST :VALUE 10 :CHILD (D E F))
    

    同样,上面的子元素是三个符号的列表。

    CL-USER 45 > (setf aaa (car (test-child test-object)))
    TEST-OBJECT2
    

    上图:该列表的第一个是符号TEST-OBJECT2

    CL-USER 46 > (test-value (symbol-value aaa))
    10
    

    上图:我们可以检索符号TEST-OBJECT2的符号值,也就是变量AAA的值。

    【讨论】:

    • 知道了。 :) 但是,您能否提出任何改进我的另一个问题的方法? :) 有什么方法可以更改代码或改进以访问 (TestObject2) 中的元素?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    相关资源
    最近更新 更多