Rakudo Perl 6 在 Scala 中是否具有类似 case Class 的结构?
Does Rakudo Perl 6 have the struct like case Class in Scala?
在 Scala 中,案例 Class 如下所示:
val alice = Person("Alice", 25, Address("1 Scala Lane", "Chicago", "USA"))
val bob = Person("Bob", 29, Address("2 Java Ave.", "Miami", "USA"))
val charlie = Person("Charlie", 32, Address("3 Python Ct.", "Boston", "USA"))
for (person <- Seq(alice, bob, charlie)) {
person match {
case Person("Alice", 25, Address(_, "Chicago", _) => println("Hi Alice!")
case Person("Bob", 29, Address("2 Java Ave.", "Miami", "USA")) => println("Hi Bob!")
case Person(name, age, _) => println(s"Who are you, $age year-old person named $name?")
}
我想在 Perl 6 中实现它,但失败了:
class Address {
has Str $.street;
has Str $.city;
has Str $.country;
}
class Person {
has Str $.name;
has Int $.age;
has $.address;
}
my $alice = Person.new(:name("Alice"), :age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA"))));
my $bob = Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA"))));
my $charlie = Person.new(:name("Charlie"), :age(32), :address(Address.new(:street("3 Python Ct."), :city("Boston"), :country("USA"))));
for ($alice, $bob, $charlie) -> $s {
given $s {
# when Person { say $alice }; # works!
when Person.new(:name("Alice"), :age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA")))) {
say "Hi Alice!"; # doesn't work
}
when Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA")))) {
say "Hi Bob!" # doesn't work
}
when Person.new(:name("Charlie"), :age(32), :address(Address.new(:street("3 Python Ct."), :city("Boston"), :country("USA")))) {
say "Who are you, $age year-old person named $name?"; # doesn't work
}
}
}
Scala 中的模式匹配似乎更强大。但是我想知道Rakudo Perl 6是否可以做到这一点?
尝试在 when
语句中使用 * eqv
来检查两个对象的结构是否相同。
class Address {
has Str $.street;
has Str $.city;
has Str $.country;
}
class Person {
has Str $.name;
has Int $.age;
has $.address;
}
my $alice = Person.new(:name("Alice"), :age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA"))));
my $bob = Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA"))));
my $charlie = Person.new(:name("Charlie"), :age(32), :address(Address.new(:street("3 Python Ct."), :city("Boston"), :country("USA"))));
for ($alice, $bob, $charlie) {
when * eqv Person.new(:name("Alice"),:age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA")))) {
say "Hi Alice!";
}
when * eqv Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA")))) {
say "Hi Bob!";
}
when Person {
say "Who are you, {.age} year-old person named {.name}?";
}
}
补充说明:
在此代码中,没有签名的 for
循环会自动设置主题(即 $_
),因此不需要 given
块。
最后一个 when
块中的 {.age}
正在访问 $_
的 .age
方法并将其插入到字符串中。
此外,由于对象与自身智能匹配,使用以下 for
循环可获得完全相同的结果:
for ($alice, $bob, $charlie) {
when $alice { say "Hi Alice!" }
when $bob { say "Hi Bob!" }
when Person { say "Who are you, {.age} year-old person named {.name}?" }
}
在 Scala 中,案例 Class 如下所示:
val alice = Person("Alice", 25, Address("1 Scala Lane", "Chicago", "USA"))
val bob = Person("Bob", 29, Address("2 Java Ave.", "Miami", "USA"))
val charlie = Person("Charlie", 32, Address("3 Python Ct.", "Boston", "USA"))
for (person <- Seq(alice, bob, charlie)) {
person match {
case Person("Alice", 25, Address(_, "Chicago", _) => println("Hi Alice!")
case Person("Bob", 29, Address("2 Java Ave.", "Miami", "USA")) => println("Hi Bob!")
case Person(name, age, _) => println(s"Who are you, $age year-old person named $name?")
}
我想在 Perl 6 中实现它,但失败了:
class Address {
has Str $.street;
has Str $.city;
has Str $.country;
}
class Person {
has Str $.name;
has Int $.age;
has $.address;
}
my $alice = Person.new(:name("Alice"), :age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA"))));
my $bob = Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA"))));
my $charlie = Person.new(:name("Charlie"), :age(32), :address(Address.new(:street("3 Python Ct."), :city("Boston"), :country("USA"))));
for ($alice, $bob, $charlie) -> $s {
given $s {
# when Person { say $alice }; # works!
when Person.new(:name("Alice"), :age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA")))) {
say "Hi Alice!"; # doesn't work
}
when Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA")))) {
say "Hi Bob!" # doesn't work
}
when Person.new(:name("Charlie"), :age(32), :address(Address.new(:street("3 Python Ct."), :city("Boston"), :country("USA")))) {
say "Who are you, $age year-old person named $name?"; # doesn't work
}
}
}
Scala 中的模式匹配似乎更强大。但是我想知道Rakudo Perl 6是否可以做到这一点?
尝试在 when
语句中使用 * eqv
来检查两个对象的结构是否相同。
class Address {
has Str $.street;
has Str $.city;
has Str $.country;
}
class Person {
has Str $.name;
has Int $.age;
has $.address;
}
my $alice = Person.new(:name("Alice"), :age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA"))));
my $bob = Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA"))));
my $charlie = Person.new(:name("Charlie"), :age(32), :address(Address.new(:street("3 Python Ct."), :city("Boston"), :country("USA"))));
for ($alice, $bob, $charlie) {
when * eqv Person.new(:name("Alice"),:age(25), :address(Address.new(:street("1 Scala Lane"), :city("Chicago"), :country("USA")))) {
say "Hi Alice!";
}
when * eqv Person.new(:name("Bob"), :age(29), :address(Address.new(:street("2 Java Ave."), :city("Miami"), :country("USA")))) {
say "Hi Bob!";
}
when Person {
say "Who are you, {.age} year-old person named {.name}?";
}
}
补充说明:
在此代码中,没有签名的 for
循环会自动设置主题(即 $_
),因此不需要 given
块。
最后一个 when
块中的 {.age}
正在访问 $_
的 .age
方法并将其插入到字符串中。
此外,由于对象与自身智能匹配,使用以下 for
循环可获得完全相同的结果:
for ($alice, $bob, $charlie) {
when $alice { say "Hi Alice!" }
when $bob { say "Hi Bob!" }
when Person { say "Who are you, {.age} year-old person named {.name}?" }
}