2017-08-29 78 views
1

跟进earlier SO question,现在我想将Fruit收集到一个篮子中,但知道子类型的出路。如何维护Chapel数组中的对象的子类型

class Banana : Fruit { 
    var color: string; 
} 
class Apple: Fruit { 
    var poison: bool; 
} 
class Fruit { 
} 

var a = new Apple(poison=true); 
var b = new Banana(color="green"); 

if (a.type == Apple) { 
    writeln("Go away doctor!"); 
} 

var basketDom = {1..1}; 
var basket: [basketDom] Fruit; 
basket.push_back(a); 
basket.push_back(b); 

for b in basket { 
    writeln(b.type:string); 
} 

这将打印超类型Fruit。我如何从这个篮子中获得ApplesBananas

+0

我不知道小教堂,但看起来像a和b在进入篮子之前正在投给水果。你似乎想要更多的东西,而不是继承Fruit。 –

回答

1

快速入侵(除非存在实际的解决方案)将发送一个元组到basket,其中元组将代表(type_of_object, typecasted_object)

您的代码将因此成为,

var basketDom = {1..1}; 
var basket: [basketDom] (string, Fruit); 
basket.push_back((a.type:string, a)); 
basket.push_back((b.type:string, b)); 

for b in basket { 
    writeln(b); 
} 

这会给你

(Apple, {poison = true}) 
(Banana, {color = green}) 

此外,您可以访问使用索引的类型。例如 - b[1]将是该类型和b[2]的对象内容。

要在此之后访问类变量,如poisoncolor,你可以不喜欢

if (b[1] == "Banana") { 
    var obj = b[2]: Banana; 
    writeln(obj.color); 
} 

相若方式和为类Apple

+1

您可以使用与C++'dynamic_cast'行为相似的显式类型转换,而不是像'string'一样携带该类型。 '如果b:Apple then writeln(“Apple”,b:Apple);'如果转换失败,返回'nil',在条件内解释为'false'。 –