Jes*_*wak 14 arrays typing range perl6 raku
我最近尝试my Array @a = 'a'..'z';
和my Array @a = @('a'..'z');
。
两者都会产生以下错误:
Type check failed in assignment to @a; expected Array but got Str ("a")
in block <unit> at <unknown file> line 1
Run Code Online (Sandbox Code Playgroud)
但是,在没有类型的情况下进行初始化会起作用,并且似乎最终会产生一个Array:
> my @a = 'a'..'z';
> @a.^name
Array
Run Code Online (Sandbox Code Playgroud)
为什么会这样呢?
rai*_*iph 12
TL; DR在这种情况下,我提供了一个相对简单的答案?但是,该解释可能不足1,因此我回顾了Declare中的一些替代方法并从范围中初始化类型化数组。
为什么会这样呢?
my @a;
声明一个新的Array
(初始化为空)并将其“绑定”到符号@a
。从而my @a; say @a.^name
回报Array
。无需Array
在数组的声明或初始化中使用该词- @
足够了。2
my @a = 'a'..'z'
试图拷贝每一个值的范围内'a'
通'z'
一个,在一个时间,到 @a[0]
,@a[1]
等绑定到新的数组@a
具有类型约束为它的每个元素(在下一节解释); 将检查每个值(并将成功)。
my Array @a
声明一个对其类型Array
具有Array
类型约束的元素(因此它是一个数组数组)。my Array @a; say @a.^name
返回Array[Array]
以表明这一点。my Array @a = 'a'..'z';
复制第一个值(“ a”)时失败,因为它不是一个Str
值Array
。
声明并初始化范围内的类型化数组
my @a = 'a'..'z';
Run Code Online (Sandbox Code Playgroud)
该my @a
语句的一部分声明了一个变量,该变量绑定到(指)一个新的type数组Array
。因为没有指定的元素类型约束,新数组元素被约束为一致Mu
时,中号 OST ü在P6 nassuming类型。换句话说,它是一个空数组,准备包含要放入其中的任何值。(可以说,say @a.^name
显示器Array
,而不是Array[Mu]
因为[Mu]
被认为是中号 OST ü ninteresting。)
... = 'a'..'z'
初始化新数组。初始化对数组已经建立的类型约束没有影响。它只是提供字符串的副本'a'
,'b'
等进了数组(自动展开迎接进入@a[0]
,@a[1]
等等)。
我建议开发人员避免对变量和显式强制值添加显式类型约束,除非他们确信它们是理想的。(请参见我在较早的SO答案结尾处的括号内的注释。)也就是说,您可以选择这样做:
my Str @a = 'a'..'z'; # `Array` elements constrained to `Str`
my Str @a = (0..99)>>.Str; # Coerce value to match constraint
Run Code Online (Sandbox Code Playgroud)
另外,P6支持显式绑定值或值列表,而不是赋值。最常见的方法是使用:=
而不是=
:
my @a := 'a'..'z'; say @a.WHAT; say @a[25]; # (Range)?z
Run Code Online (Sandbox Code Playgroud)
注意如何明确的结合@a
方式@a
一直没有被绑定到一个新的Array
,而是到Range
价值。并且因为a Range
可以表现为a Positional
,所以位置下标仍然有效。
以下语句将成为完全多余的显式键入,但它们的工作原理和结果彼此完全相同,尽管第一个语句会更快:
my Str @a := Array[Str].new('a'..'z');
my Str @a = Array[Str].new('a'..'z');
Run Code Online (Sandbox Code Playgroud)
关于此主题还有更多的要讨论的内容,但也许前面的内容已足以解决该问题/答案。如果不是,请在原始问题和/或下面的评论中提出其他问题。
1此答案的早期版本始于:
my Array @a ...
# My array of thoughts raised by this declaration
# and your questing "why?" in this SO question
# began with wry thoughts about complicated answers
# about reasons your array is awry and pedances
Run Code Online (Sandbox Code Playgroud)
(我将“ pedances”一词组成的意思是看似学究的东西,但在正确使用时会很好地流动-一旦您熟悉其明显特质但实际上很有帮助的性质,就会自然发生。更重要的是,我需要一些东西与“答案”押韵。)
2以下是一些@
P6中含义的助记符:
它看起来像是一个零数字(0
),其中带有(Math Italic Small A)–并且
@foo
变量默认为0
索引(或
@
)。
这听起来像单词“在”。数组在索引处具有元素。
设置数组中元素的类型:
my Str @a = 'a'..'z';
say @a; #[a b c d e f g
Run Code Online (Sandbox Code Playgroud)
要查看它是什么类型,可以使用.WHAT
my Str @a = 'a'..'z';
say @a.WHAT #(Array[Str])
Run Code Online (Sandbox Code Playgroud)
要测试它是否为数组,可以进行智能匹配
my Str @a = 'a'..'z';
say 'is array' if @a ~~ Array; #is array
say 'is str array' if @a ~~ Array[Str]; #is str array
say 'is str array' if @a ~~ Array[Int]; #
Run Code Online (Sandbox Code Playgroud)
在@('a'..'z')
将一个List
不是Array
。将其更改为
['a'..'z']
将给出一个Array
。
但这仍然会在您将其分配给您时给您一个类型错误my Array @a
。
如果要将整个数组分配给另一个数组的元素,则必须以某种方式逐项列出,例如:
$[1,2,3]; #Still an array but treated as single item
[1,2,3], ; #Note the list operator (comma), this give you a list of lists
Run Code Online (Sandbox Code Playgroud)
因此,在您的情况下:
'a'..'z';
是一个范围,需要转换为数组,所以
['a'..'z'];
现在将范围评估为数组
$['a'..'z'];
现在将范围评估为数组并作为单个项目
my Array @a=$['a'..'z'];
say @a;
#OUTPUT:
#[[a b c d e f g h i j k l m n o p q r s t u v w x y z]]
# Which is an array of arrays;
Run Code Online (Sandbox Code Playgroud)
不知道这是您要追求的,但是它消除了类型错误。
归档时间: |
|
查看次数: |
206 次 |
最近记录: |