如何使用common lisp defenum在不同的枚举类中定义一些相同的枚举类型

问题描述 投票:0回答:1

抱歉,我英语不好... 我定义了 2 个枚举使用 defenum

(in-package :useragentutils-cl)

;; name is key world so change planet-name
(defenum:defenum (Manufacturer (:initargs (id namee)))
         ((OTHER(1 "Other"))
      (MICROSOFT(2 "Microsoft Corporation"))
      (APPLE(3 "Apple Inc."))
      (SUN(4 "Sun Microsystems, Inc."))
      (SYMBIAN(5 "Symbian Ltd."))
      (NOKIA(6 "Nokia Corporation"))
      (BLACKBERRY(7 "Research In Motion Limited"))
      (HP(8 "Hewlett Packard"))
      (SONY_ERICSSON(9 "Sony Ericsson Mobile Communications AB"))
      (SAMSUNG(20 "Samsung Electronics"))
      (SONY(10 "Sony Computer Entertainment, Inc."))
      (NINTENDO(11 "Nintendo"))
      (OPERA(12 "Opera Software ASA"))
      (MOZILLA(13 "Mozilla Foundation"))
      (GOOGLE(15 "Google Inc."))
      (COMPUSERVE(16 "CompuServe Interactive Services, Inc."))
      (YAHOO(17 "Yahoo Inc."))
      (AOL(18 "AOL LLC."))
      (MMC(19 "Mail.com Media Corporation"))
      (AMAZON(24 "Amazon.com, Inc."))
      (ROKU(21 "Roku, Inc."))
      (ADOBE(23 "Adobe Systems Inc."))
      (CONONICAL(25 "Canonical Ltd."))
      
          )
         
         ((id)
          (namee)
          )

    
         )
(in-package :useragentutils-cl)

(defenum:defenum (RenderingEngine (:initargs (namee)))
    ((EDGE_HTML 1 ("EdgeHTML"))
     (TRIDENT 2 ("Trident"))
     (WORD("Microsoft Office Word"))
     (GECKO("Gecko"))
     (WEBKIT("WebKit"))
     (PRESTO("Presto"))
     (MOZILLA("Mozilla"))
     (KHTML("KHTML"))
     (BLINK("Blink"))
     (OTHER("Other"))

     )
    ((namee))
    ())

当我编译 RenderingEngine 时出现错误

Execution of a form compiled with errors.
Form:
  (IT.UNIMIB.DISCO.MA.COMMON-LISP.EXTENSIONS.DATA-AND-CONTROL-FLOW.DEFENUM:DEFENUM
 (RENDERINGENGINE (:INITARGS (NAMEE)))
 ((EDGE_HTML 1 ("EdgeHTML")) (TRIDENT 2 ("Trident"))
  (WORD ("Microsoft Office Word")) (GECKO ("Gecko")) (WEBKIT ("WebKit"))
  (PRESTO ("Presto")) (MOZILLA ("Mozilla")) (KHTML ("KHTML")) (BLINK ("Blink"))
  (OTHER ("Other")))
 ((NAMEE)) NIL)
Compile-time error:
  (during macroexpansion of (IT.UNIMIB.DISCO.MA.COMMON-LISP.EXTENSIONS.DATA-AND-CONTROL-FLOW.DEFENUM:DEFENUM
 (RENDERINGENGINE #) ...))
Tag MOZILLA is part of enum MANUFACTURER; it cannot be added to enum RENDERINGENGINE.
   [Condition of type SB-INT:COMPILED-PROGRAM-ERROR]

我查看源代码

(loop for (tag tag-id) in ',tags-specs do
              (setf (get tag '%%enum%%) e
                    (gethash tag-id id-map) (tag-of e (the symbol tag))))

我猜'%%enum%%是一个带有标签的plist,一对一,我的想法是设置e为零,当我这样做时 并编译 RenderingEngine 我遇到了另一个错误

The constant MOZILLA is being redefined (from 13 to 7)
   [Condition of type SB-EXT:DEFCONSTANT-UNEQL]
See also:
  Common Lisp Hyperspec, DEFCONSTANT [:macro]
  SBCL Manual, Idiosyncrasies [:node]

所以我再次查看源代码我得到了这个

  ;; Building init code.
  (let ((tags-defconstants
         (loop for (tag tag-id) in tags-specs
               unless (keywordp tag)
               if (numberp tag-id)
               collect `(defconstant ,tag ,tag-id)
               else if (and (listp tag-id) (eq 'eql (first tag-id)))
               collect `(defconstant ,tag ,(second tag-id))))
        )

defconstant 定义一个标签。

在java中枚举类可以定义一些相同的枚举类型

package com.jq;

public enum Manufacturer {
    
    MOZILLA(13, "Mozilla Foundation");
    
    private final short id;
    private final String name;
    
    private Manufacturer(int id, String name) {
        this.id = (byte) id;
        this.name = name;
    }

    /**
     * @return the id
     */
    public short getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

}


public enum RenderingEngine {
    
    MOZILLA(13, "Mozilla Foundation");
    
    private final short id;
    private final String name;
    
    private RenderingEngine(int id, String name) {
        this.id = (byte) id;
        this.name = name;
    }

    /**
     * @return the id
     */
    public short getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

}
enums lisp common-lisp
1个回答
0
投票

以下内容无法按您想要的方式工作:

(defenum t1 (a b c))
(defenum t2 (b c d))

这是因为在使用

b
库时,
c
defenum
只能属于一个枚举(枚举类型的另一种实现可能允许这样做)。这是故意的。您可以使用包来拥有具有相同
symbol-name
的不同符号:

(defpackage t1 (:use) (:export #:a #:b #:c))
(defpackage t2 (:use) (:export #:b #:c #:d))

在上面,

t1:b
t2:b
是不同的符号,具有相同的名称。这允许您管理命名限制,以防两个不同的枚举具有冲突的值。例如,
color:orange
fruit:orange
是在不同上下文中使用的两个具有相同名称的符号。

您可以按如下方式定义不同的枚举:

(defenum t1 (t1:a t1:b t1:c))
#<ENUM T1 (T1:A T1:B T1:C)>

和:

(defenum t2 (t2:b t2:c t2:d))
#<ENUM T2 (T2:B T2:C T2:D)>
© www.soinside.com 2019 - 2024. All rights reserved.