gpt4 book ai didi

chapel - 如何在教堂中保留可接受类型的列表以进行比较

转载 作者:行者123 更新时间:2023-12-04 18:01:13 26 4
gpt4 key购买 nike

假设我有类(class) Student , BadStudent:Student , GoodStudent:StudentExcellentStudent: Student .我想要一个只对 Good 进行操作的类方法和 Exceptional学生们。就像是:

class AdvancedBasketWeaving {

// this is the question:
var acceptableStudentTypes: [1..2] = [GoodStudent, ExcellentStudent];

proc accept(student: Student) {
for at in this.acceptableStudentTypes {
if student.type == at then return "YES!";
}
return "Computer says 'No'";
}
}

如何获得此功能?

最佳答案

我认为您需要将两种工具用于此模式:

1) 第一个是 Chapel 的类型转换运算符 ( : )。对于类,强制转换类似于 C++ 的动态强制转换。简而言之,给定一个类对象,如 GoodStudent 的以下实例:

var brian = new GoodStudent();

将对象转换为类类型将返回 nil如果对象不是该类的子类,如果是则类引用。因此:
...(brian: Student != nil)...           // will evaluate to true
...(brian: BadStudent != nil)... // will evaluate to false
...(brian: GoodStudent != nil)... // will evaluate to true
...(brian: ExcellentStudent != nil)... // will evaluate to false

因此,要测试 GoodStudentExcellentStudent ,你可以写:
if (student:GoodStudent != nil || student:ExcellentStudent != nil) then
return "YES!";

或者,如果每个 ExcellentStudent也是 GoodStudent ,您可以考虑将其设为 GoodStudent 的子类在你的类层次结构中,而不是它的兄弟。在这种情况下,您可以简单地将条件写为:
if student:GoodStudent != nil then return "YES!";

因为这两个 GoodStudentExcellentStudent将为此条件返回 true。

作为重要说明,将这个条件简单地写为:
if student.type == GoodStudent

但这不会在您的过程的上下文中给出正确的行为,因为它声明如下:
proc accept(student: Student) { ... }

具体来说, .type查询将返回类对象的静态(编译时)类型,在此例程的上下文中, student 的静态类型是 Student由于它的正式类型。所以比较它的静态类型永远不会匹配 GoodStudent ,即使对象的动态类型是 GoodStudent .使用动态转换通过将静态测试更改为动态测试来解决此问题。另一种方法是使 accept()程序完全通用,如下:
proc accept(student) { ... }

但随后你通过允许其他非 Student 来打开闸门要传入的类型。

2)您需要的第二件事(以及您问题的重点)是元组类型,这可能是创建类型集合的最佳/最轻量级方式。 Chapel 仅支持值数组,不支持类型,因此代码中的以下行是不合法的:
var acceptableStudentTypes: [1..2] = [GoodStudent, ExcellentStudent];

相反,创建一个元组类型来存储您要比较的所有类型:
type acceptableStudentTypes = (GoodStudent, ExcellentStudent);

这导致了我建议的解决方案( try it online ):
class Student {
}

class BadStudent: Student {
}

class GoodStudent: Student {
}

class ExcellentStudent: Student {
}

// a tuple of acceptable types
type acceptableStudentTypes = (GoodStudent, ExcellentStudent);

class AdvancedBasketWeaving {
proc accept(student: Student) {
// iterate over the tuple's size
for param i in 1..acceptableStudentTypes.size do
// see if dynamically casting the student to the type "works"
if student: acceptableStudentTypes(i) != nil then
return "YES!";
return "Computer says 'No'";
}
}

var course = new AdvancedBasketWeaving();
writeln(course.accept(new Student())); // Computer says 'No'
writeln(course.accept(new BadStudent())); // Computer says 'No'
writeln(course.accept(new GoodStudent())); // YES!
writeln(course.accept(new ExcellentStudent())); // YES!

请注意,我已经移动了 acceptableStudentTypes从类范围(这是合乎逻辑的,你有它的地方)到模块范围的声明。这是因为 Chapel 中有一个明显的错误,我在 filed an issue against .

或者,如果您可以制作 ExcellentStudent GoodStudent 的子类,我认为以下更好( try it online ):
class Student {
}

class BadStudent: Student {
}

class GoodStudent: Student {
}

class ExcellentStudent: GoodStudent {
}

class AdvancedBasketWeaving {
proc accept(student: Student) {
if student: GoodStudent != nil then
return "YES!";
return "Computer says 'No'";
}
}

var course = new AdvancedBasketWeaving();
writeln(course.accept(new Student())); // Computer says 'No'
writeln(course.accept(new BadStudent())); // Computer says 'No'
writeln(course.accept(new GoodStudent())); // YES!
writeln(course.accept(new ExcellentStudent())); // YES!

关于chapel - 如何在教堂中保留可接受类型的列表以进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50478234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com