In Match§
有关infix eqv,请参阅主要文档 在上下文中
multi infix:<eqv>(Match \a, Match \b)
如果 a
和 b
的 pos
、from
和 orig
属性相等,并且 made
、Capture::list
和 Capture::hash
相同或都未定义,则返回 True
。
In Operators§
有关infix eqv,请参阅主要文档 在上下文中
sub infix:<eqv>(Any, Any)
这可以称为 等价运算符,如果两个参数在结构上相同,即来自同一种类型并且(递归地)包含等价值,它将返回 True
。
say [1, 2, 3] eqv [1, 2, 3]; # OUTPUT: «True»say Any eqv Any; # OUTPUT: «True»say 1 eqv 2; # OUTPUT: «False»say 1 eqv 1.0; # OUTPUT: «False»
惰性 Iterable
无法比较,因为它们被假定为无限的。但是,如果两个惰性 Iterable
的类型不同,或者只有一个 Iterable
是惰性的,则该运算符将尽力而为并返回 False
。
say (1…∞) eqv (1…∞).List; # Both lazy, but different types; OUTPUT: «False»say (1…∞) eqv (1…3); # Same types, but only one is lazy; OUTPUT: «False»(try say (1…∞) eqv (1…∞)) # Both lazy and of the same type. Cannot compare; throws.orelse say $!.^name; # OUTPUT: «X::Cannot::Lazy»
在某些情况下,它将能够比较惰性操作数,只要它们可以迭代
my = lazy ^2;my = ;.cache;say eqv ; # OUTPUT: «True»
当缓存时,可以迭代两个惰性 Seq
,从而进行比较。
默认的 eqv
运算符甚至可以与任意对象一起使用。例如,eqv
将认为同一对象的两个实例在结构上是等价的
mysay A.new(a => 5) eqv A.new(a => 5); # OUTPUT: «True»
尽管上面的示例按预期工作,但 eqv
代码可能会回退到较慢的代码路径以完成其工作。避免这种情况的一种方法是实现一个适当的前缀 eqv
运算符
mymulti infix:<eqv>(A , A )say A.new(a => 5) eqv A.new(a => 5); # OUTPUT: «True»
请注意,eqv
不会对每种容器类型的递归工作,例如 Set
mysay Set(A.new(a => 5)) eqv Set(A.new(a => 5)); # OUTPUT: «False»
即使两个集合的内容是 eqv
,但集合不是。原因是 eqv
将相等性检查委托给 Set
对象,该对象依赖于元素级的 ===
比较。通过为类 A
提供 WHICH
方法将其转换为值类型 (ValueObjAt
) 会产生预期的行为
mysay Set(A.new(a => 5)) eqv Set(A.new(a => 5)); # OUTPUT: «True»
您可以使用运算符的全名调用其单参数版本;它将始终返回 true。
say infix:<eqv>(33); # OUTPUT: «True»say infix:<eqv>(False); # OUTPUT: «True»
In Allomorph§
有关infix eqv,请参阅主要文档 在上下文中
multi infix:<eqv>(Allomorph , Allomorph --> Bool)
如果两个 Allomorph
$a
和 $b
属于同一种类型,它们的 Numeric
值 相等,并且它们的 Str
值也 相等,则返回 True
。否则返回 False
。
In ObjAt§
有关infix eqv,请参阅主要文档 在上下文中
multi infix:<eqv>(ObjAt , ObjAt )
如果两个 ObjAt 相同,即它们标识的对象相同,则返回 True。
my = [2,3,1];my := ;say .WHICH eqv .WHICH; # OUTPUT: «True»