我能否在一行上编写多个Raku类型的智能匹配?

13

我知道这样做是不起作用的,因为我已经尝试过:

if $r ~~ BearingTrue || CompassAdj || CourseAdj { nextsame };

但是 - 是否有一种简洁明了、易读的方法来在同一行上执行多个类型智能匹配,而不必扩展到给定/when或if/else结构?


嗨,p6steve,我尝试了你的代码和下面@Scimon_Proctor的答案,但我一直收到“未声明名称”的错误,例如BearingTrue等。有什么提示吗? - jubilatious1
1
嗨@jubilatious1 - 我的代码片段在raku模块的主体中,因此您需要使用zef安装该模块,并在代码中使用use才能使用这些名称。此外,虽然'|'连接符可以正常工作,但我意识到通过测试它不应该是一件事情,而不是三件事情,我的代码会更清晰...请参见我的新“答案”或最终版本。 - librasteve
2个回答

15

你尝试过:

if $r ~~ BearingTrue | CompassAdj | CourseAdj { nextsame };

这将为您提供一个任意交叉点,然后匹配 OK。


嗨@scimon - 这就是诀窍(我曾尝试过<xx yy>.any...我一定是误用了,这让我迷失了方向)- 有点尴尬。 - librasteve
1
@p6steve 可能没有起作用的原因是 <...> 创建了一个 StrList。 因此,您正在与字符串进行智能匹配,而不是类型。 if $r ~~ (BearingTrue、CompassAdj、CourseAdj).any { nextsame } 应该可以正常工作。 顺便说一句,这似乎是使用 if 的语句修饰符版本的好机会:nextsame if $r ~~ (BearingTrue、CompassAdj、CourseAdj).any; - uzluisf

1
这个答案是为了让我更清楚地回应@jubilatious1的评论。
我正在开发一个新的Raku模块,可以在这里看到大约225行 Physics::Navigation
为了说明问题,代码现在看起来像这样...
class BearingTrue { ...}
class BearingMag  { ...}

sub err-msg { die "Can't mix BearingTrue and BearingMag for add/subtract!" }

class BearingTrue is Bearing is export {

    multi method compass { <T> }                        #get compass

    multi method compass( Str $_ ) {                    #set compass
        die "BearingTrue compass must be <T>" unless $_ eq <T> }

    method M {                                          #coerce to BearingMag
        my $nv = $.value + ( +$variation + +$deviation );
        BearingMag.new( value => $nv, compass => <M> )
    }

    #| can't mix unless BearingMag 
    multi method add( BearingMag ) { err-msg }
    multi method subtract( BearingMag ) { err-msg }
}

所以我决定重新编写代码,使用多方法的加法和减法来检查类型匹配,以防止一个迷失的水手将磁方位角添加到真实的方位角上。我认为这比Scimon的好答案更清晰,因为在那种情况下,我的方法接受了所有Bearing子类型,然后使用if语句来检测类型错误。
欢迎您继续...
zef install https://github.com/p6steve/raku-Physics-Navigation.git

接着参考bin/synopsis-navigation.raku顶部的示例使用该模块,并在自己的代码中使用各种类。

如果你只是想看看这些组件是如何配合的,我建议按照相似的思路编写自己的简单类,并通过书籍(如ThinkRaku第12章)中的示例进行学习。我推荐这个学习方法,因为它提供了清晰的信息和等同对待继承和角色。

我相信其他人会认为我的代码风格过于依赖继承。我认为,由于磁轴承严格来说是从一般轴承导出的概念,所以这对我的代码来说是正确的--但是角色和组合不太受限制,并提供了更好的可维护性的封装。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接