例如,我有一个Array数字:
> my @a = ^5
[0 1 2 3 4]
Run Code Online (Sandbox Code Playgroud)
我想打印他们的方块.我可以使用map,但它也会返回一个修改过的List(这五个True),我不想要:
> @a.map({ put $_**2 })
0
1
4
9
16
(True True True True True)
Run Code Online (Sandbox Code Playgroud)
我找到的唯一方法是使用hyper >>:
> @a>>.&{ put $_**2 }
0
1
4
9
16
Run Code Online (Sandbox Code Playgroud)
但
hyper怎么办?那么正确的方法是什么?
PS当然,我可以使用map然后put结果:
.put for @a.map: {$_**2 }
Run Code Online (Sandbox Code Playgroud)
但这不是我想要的.
Jon*_*ton 13
使用map就可以用于此目的,因为在sink上下文中它不会产生结果列表.在REPL中,需要结果map,因此它的产生原因.但在一个案例中:
@a.map({ put $_**2 });
say "That's all, folks";
Run Code Online (Sandbox Code Playgroud)
然后map不想要结果,因此不会组装结果列表.如果希望真正拼出这个,可以写:
sink @a.map({ put $_**2 })
Run Code Online (Sandbox Code Playgroud)
请注意,例程中的最后一个语句将被视为隐式返回值.使用--> Nil将足以确保最终map在sink上下文中.
sub put-squares(@a --> Nil) {
@a.map({ put $_**2 })
}
Run Code Online (Sandbox Code Playgroud)
首先,使用>>.是不是一个好主意,因为订单中的操作进行的,所以不保证在任何特定的顺序.
你可以使用WhateverCode:
.say for @a.map: * ** 2
Run Code Online (Sandbox Code Playgroud)
我个人认为最具可读性.或者,您可以使用占位符变量:
.say for @a.map: { $^value ** 2 }
Run Code Online (Sandbox Code Playgroud)
或者完全写出来:
.say for @a.map: { $_ ** 2 }
Run Code Online (Sandbox Code Playgroud)
但显然你不希望如此.为什么?
这个答案是对其他答案的补充.假设你和其他读者对FP ish方法的某些可能性感兴趣而避免纯粹主义,我会围绕你的问题徘徊.
my @a = ^5; # @a bound to an Array
@a.map(* ** 2) .put; # 0 1 4 9 16
@a.put; # 0 1 2 3 4 <- Array unchanged
@a.map(* **= 2) .put; # 0 1 4 9 16
@a.put; # 0 1 4 9 16 <- Array changed
@a := @a.List; # rebind @a to a List
@a.map(* ** 2) .put; # 0 1 16 81 256 <- Same as if Array
@a.put; # 0 1 4 9 16 <- List unchanged
@a.map(* **= 2) .put; # Cannot assign to an immutable value
Run Code Online (Sandbox Code Playgroud)
该Array实例告诉你如何可以选择性变异顺便.(它使用表单中的二进制(中缀)操作op=而不仅仅是op但如果这令人困惑只是注意效果并忽略语法.)
En passant变种比单纯的更加"邪恶"的副作用.put,如果有人称之为"功能"风格,纯粹主义者会有点恐惧.当然不是我.:)
这个List例子走向另一个方向,走向不变性.Lists是不可改变的崇拜者.
再次,那些进入FP的人可能会赞扬他们的不变性.纯粹主义者将诋毁崇拜者的方面.Perl民众可能会双管齐下.
A List完全或大部分是不可变的.
你永远不能推或弹List.
它的长度总是不可变的.
基本值列表完全不可变:
my $really-immutable-list = (1,2,'foo', 1.5, (3,4,5));
Run Code Online (Sandbox Code Playgroud)
例外情况是,如果列表的一个元素本身是可变的,那么你可以改变它,从而改变List:
my $only-shallowly-immutable-list = (1,2,'foo', 1.5, [3,4,5]);
$only-shallowly-immutable-list[4][1] = 9;
say $only-shallowly-immutable-list; # (1 2 foo 1.5 [3 9 5])
Run Code Online (Sandbox Code Playgroud)
更巧妙的是:
class c { has $.foo; method waldo { $!foo = 42 } }
my $bar = c.new;
my $list = ($bar, 2);
say $list; # (c.new(foo => Any) 2)
$bar.waldo;
say $list; # (c.new(foo => 42) 2)
Run Code Online (Sandbox Code Playgroud)