为什么不能在没有滑动的情况下将手动创建的 Pair 传递给方法?
Why can't pass a manually created Pair to method without a slip?
:5hours
是一个Pair
,hours => 5
也是一个Pair
:
> DateTime.now.truncated-to('day').later(:5hours)
2022-02-14T05:00:00+08:00
> :5hours.WHAT
(Pair)
> DateTime.now.truncated-to('day').later(hours => 5)
2022-02-14T05:00:00+08:00
> (hours => 5).WHAT
(Pair)
但是,当我手动创建 Pair
时,它与 later
:
的签名不匹配
> DateTime.now.truncated-to('day').later(Pair.new('hours', 5))
Cannot resolve caller later(DateTime:D: Pair:D); none of these signatures match:
(Dateish:D: *%unit --> Dateish:D)
(Dateish:D: @pairs, *%_)
in block <unit> at <unknown file> line 1
但是在Pair
参数之前用一个垂直的就可以了:
> DateTime.now.truncated-to('day').later(|Pair.new('hours', 5))
2022-02-14T05:00:00+08:00
那么:5hours
、Pair.new('hours', 5)
和hours => 5
有什么区别呢?为什么不能将手动创建的 Pair
如 Pair.new('hours', 5)
传递给 later
方法?
下面这两个不是一回事吧?
> :5hours === Pair.new('hours', 5) === hours => 5
True
> :5hours eqv Pair.new('hours', 5) eqv hours => 5
True
> my $pair1 = Pair.new('hours', 5); dd $pair1; # Pair $pair1 = :hours(5)
> my $pair2 = :5hours; dd $pair2; # Pair $pair2 = :hours(5)
> my $pair3 = hours => 5; dd $pair3; # Pair $pair3 = :hours(5)
> my $pair4 = 'hours' => 5; dd $pair4; # Pair $pair4 = :hours(5)
虽然:5hours
和hours => 5
和:hours(5)
和Pair.new(hours,5)
和Pair.new(key => "hours", value => 5)
都是创建Pair
对象的不同方法,只有前三个 是表示命名参数的语法糖。
当您将 Pair.new("hours",5)
作为参数传递时,它被视为 Positional 参数。观察:
sub foo(*@_, *%_) {
dd @_, %_
}
foo hours => 5;
# []
# {:hours(5)}
foo Pair.new("hours",5);
# [:hours(5)]
# {}
至于为什么会这样?好吧,有时你想传递一个 Pair
作为位置参数。如果 Pair
始终被认为是命名参数,您将无法这样做。
至于为什么 |Pair.new("hours",5)
作为命名参数?此上下文中的 |
将给定对象(通常是 Capture
或 Hash
/Map
)展平为给定子例程的参数。在这种情况下,Pair
被视为 Map
的退化情况:具有单个键/值的不可变 Map
。观察:
foo |Pair.new("hours",5);
# []
# {:hours(5)}
嗯,可能是 Associative
:-)
say Pair ~~ Associative; # True
.say for (:5hours).keys; # hours
.say for (:5hours).values; # 5
最后,此上下文中的 |
在技术上 不是 一个 Slip
,而是将给定值扁平化为调用参数的语法糖.
语法早于 Slip
的概念(2015 年在 Great List Refactor 期间引入)。只是在 2015 年很晚的时候,|
才被@Larry 确定也可以用来表示 Slip
,因为他们 概念上 做类似的事情。
:5hours
是一个Pair
,hours => 5
也是一个Pair
:
> DateTime.now.truncated-to('day').later(:5hours)
2022-02-14T05:00:00+08:00
> :5hours.WHAT
(Pair)
> DateTime.now.truncated-to('day').later(hours => 5)
2022-02-14T05:00:00+08:00
> (hours => 5).WHAT
(Pair)
但是,当我手动创建 Pair
时,它与 later
:
> DateTime.now.truncated-to('day').later(Pair.new('hours', 5))
Cannot resolve caller later(DateTime:D: Pair:D); none of these signatures match:
(Dateish:D: *%unit --> Dateish:D)
(Dateish:D: @pairs, *%_)
in block <unit> at <unknown file> line 1
但是在Pair
参数之前用一个垂直的就可以了:
> DateTime.now.truncated-to('day').later(|Pair.new('hours', 5))
2022-02-14T05:00:00+08:00
那么:5hours
、Pair.new('hours', 5)
和hours => 5
有什么区别呢?为什么不能将手动创建的 Pair
如 Pair.new('hours', 5)
传递给 later
方法?
下面这两个不是一回事吧?
> :5hours === Pair.new('hours', 5) === hours => 5
True
> :5hours eqv Pair.new('hours', 5) eqv hours => 5
True
> my $pair1 = Pair.new('hours', 5); dd $pair1; # Pair $pair1 = :hours(5)
> my $pair2 = :5hours; dd $pair2; # Pair $pair2 = :hours(5)
> my $pair3 = hours => 5; dd $pair3; # Pair $pair3 = :hours(5)
> my $pair4 = 'hours' => 5; dd $pair4; # Pair $pair4 = :hours(5)
虽然:5hours
和hours => 5
和:hours(5)
和Pair.new(hours,5)
和Pair.new(key => "hours", value => 5)
都是创建Pair
对象的不同方法,只有前三个 是表示命名参数的语法糖。
当您将 Pair.new("hours",5)
作为参数传递时,它被视为 Positional 参数。观察:
sub foo(*@_, *%_) {
dd @_, %_
}
foo hours => 5;
# []
# {:hours(5)}
foo Pair.new("hours",5);
# [:hours(5)]
# {}
至于为什么会这样?好吧,有时你想传递一个 Pair
作为位置参数。如果 Pair
始终被认为是命名参数,您将无法这样做。
至于为什么 |Pair.new("hours",5)
作为命名参数?此上下文中的 |
将给定对象(通常是 Capture
或 Hash
/Map
)展平为给定子例程的参数。在这种情况下,Pair
被视为 Map
的退化情况:具有单个键/值的不可变 Map
。观察:
foo |Pair.new("hours",5);
# []
# {:hours(5)}
嗯,可能是 Associative
:-)
say Pair ~~ Associative; # True
.say for (:5hours).keys; # hours
.say for (:5hours).values; # 5
最后,此上下文中的 |
在技术上 不是 一个 Slip
,而是将给定值扁平化为调用参数的语法糖.
语法早于 Slip
的概念(2015 年在 Great List Refactor 期间引入)。只是在 2015 年很晚的时候,|
才被@Larry 确定也可以用来表示 Slip
,因为他们 概念上 做类似的事情。