【问题标题】:The Proper Class Design For Designing a Language Type System设计语言类型系统的正确类设计
【发布时间】:2011-06-27 12:01:52
【问题描述】:

我正在为自己的目的设计一种语言。它将基本上有两个实体,功能和类型。例如

Object1 = CreateObject1("param1", "param2", 23 ) //Line 1
Object3 = Object1 + Object2 //Line 2
Evaluate(Object3) //Line 3

第 2 行评估 Object1 类型的对象是否为 Object2 的“+”,如果是,则将创建一个结果对象并将其分配给 Object3。变量定义类似于 Java Script 中的 var 关键字。

我心目中的设计就像创建一个基础“值”类(具有加、减、乘、除等基本操作),每个子对应于我计划在语言中摄取的不同类型。

class Value{
 Value add(Value value)
 ..
}

class Integer extends Value{
 Value add(Value value){
    //if value is compatible to add with Integer type then return the appropriate     
    //resultant object else throw exception.
 }
}

我可以很容易地创建这样的子类,但是如果一个函数更改了对象的属性(例如更改了类的成员值),那么我需要将其向下转换为该类型并更新适当的属性。

class ABC extends Value{
 Value add(Value value){
 //
 }

 private int X;
 private int Y;
 private int Z;
 private string XYZ;

 public setX(int x){
   this.X = x;
 }
 .
 .
}

ObjectABC = GetABC();
SetX(ObjectABC, 1)

在函数 SetX() 的实现中。我会做这样的事情:

ABC abc = (ABC)ObjectABC; //ObjectABC will be a Value type here.
abc.setX( 1 );

我想摆脱这种向下铸造的东西。可以做到吗?请指教。

【问题讨论】:

  • 通常有一些方法可以消除强制转换,但我认为您需要提供更多关于您正在做什么的信息。例如,谁定义了 ABC 对象?是用您的语言定义的还是用 Java 定义的?至少,试着用你的语言展示一个完整的示例程序。
  • ABC 是我的语言中 ObjectABC 对象的实现细节。语言结构是这样的。 /*@list 将有 Employee 对象*/ @employeeList = GetEmployess("AdminBlock") /*@avgSalary 将有 double 值 */ @avgSalary = GetAvgSalary(@list) @SumCalculation = ( @avgSalary * 33 ) / 100跨度>

标签: language-design type-systems


【解决方案1】:

你可以像这样使用双重调度:

abstract class Value {
   Value add(Value v) { throw new InvalidArgumentException("add", getClass(), v); }
   Value addInteger(Integer i);

   Value divide(Value) { throw new InvalidArgumentException("divide", getClass(), v); }
   Value divideIntegerReversed(Integer i);

}

class Integer extends Value {
   @Override
   Value add(Value v) {
     return v.addInteger(this);
   }

   @Override      
   Value addInteger(Integer other) {
      // note the argument reversal but not worries because addition is commutative
      return whtvr;
   }

   @Override
   Value divide(Value v) {
     return v.divideIntegerReversed(this);
   }

   @Override
   Value divideIntegerReversed(Integer nom) {
     // note that we now want `nom / this` and not `this / nom`
     return wthvr;
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2011-08-23
    • 2015-08-24
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    相关资源
    最近更新 更多