是否有可扩展枚举的编程语言?

时间:2015-07-24 03:18:51

标签: enums extends

许多面向对象的语言允许扩展类:

class Animal {}
class Cat extends Animal {}
class Dog extends Animal {}

但是,在使用枚举时,有些情况需要相反的功能。例如:

enum CatAction {
    meow, eat, sleep
}

enum DogAction {
    bark, fetch, eat, sleep
}

enum AnimalAction {
    eat, sleep
}

这里有一些冗余。 AnimalAction必须是CatAction,因为如果任意Animal可以执行操作,则Cat可以按定义执行。但是,即使具有多重继承的语言也不允许定义enum AnimalAction extends CatAction, DogAction {},此外,该语法不会避免冗余。

可以使用generalizes或类似关键字修复此问题。

enum AnimalAction {
    eat, sleep
}

enum CatAction generalizes AnimalAction {
    meow
}

enum DogAction generalizes AnimalAction {
    bark, fetch
}

此功能还使一些模式更方便:

enum Direction2D {
    North, East, South, West
}

enum Direction3D generalizes Direction2D {
    Up, Down
}

是否有任何编程语言支持此功能?

2 个答案:

答案 0 :(得分:1)

在我看来,

C ++。

struct Animal{
  enum{
    eat,
    sleep
  };
};

struct Cat : Animal{
  enum{
    meow,
    glare,
    hiss
  };
};

struct Dog : Animal{
  enum{
    bark,
    fetch,
    peeOnCarpet
  };
};

枚举值与声明枚举的范围相同。但是每个枚举的第一个元素从零开始,所以除非你有特定的animal / derivedAnimal函数,否则你可能希望确保每个元素都是唯一的。

你可以通过在每个基类中添加一个标记来解决这个问题,我不确定我是否喜欢它,但是它有效。

此代码是为Arduino(C ++)编写的。

struct Animal{
  enum Action{
    eat,
    sleep,
    die,
    end
  };
};

struct Dog : Animal{
  enum Action{
    bark = Animal::Action::end,
    fetch,
    peeOnCarpet
  };
};

void setup() {

  Dog d;
  Serial.begin(9600);
  Serial.println( "Values: " );
  Serial.println( d.eat, DEC );
  Serial.println( d.sleep, DEC );
  Serial.println( d.die, DEC );
  Serial.println( d.bark, DEC );
  Serial.println( d.fetch, DEC );
  Serial.println( d.peeOnCarpet, DEC );
}

void loop() { }

答案 1 :(得分:1)

OCaml的多态变体很接近(尽管与枚举不同,它们不是数字)。

以下是例子:

type animal_action = [`Eat | `Sleep]

type cat_action = [animal_action | `Meow]

type dog_action = [animal_action | `Woof]

您可以有多个包含,但它是包含:这会导致cat_actiondog_action中的构造函数联合。

type catdog_action = [cat_action | dog_action]
(* [`Eat | `Sleep | `Meow | `Woof] : that is, not what you wanted. *)

多态变体实际上比这个例子更复杂,但我不认为进入细节会有助于回答你的问题。