2016-10-09 1 views
4

Это выглядит, как будто скалярное сам по себе является своим родом список одного пункта:Почему я вижу странное поведение индекса на скалярах?

> "foo"[1] 
Index out of range. Is: 1, should be in 0..0 
    in block <unit> at <unknown file> line 5 

> "foo"[0] 
foo 
> "foo"[*-1] 
foo 

Я говорю то список один, так как списки, кажется, не имеют диапазон от их индексов:

> (0, 1, 2)[3] 
Nil 

Что здесь происходит. Что я не понимаю об операторе [].

+0

Разве вы не смотрите на (0, 1, 2) [2], поскольку нет третьего элемента этого списка? – BarneySchmale

+0

@BarneySchmale Я демонстрирую разницу в поведении вне диапазона между сортировкой по шкале (dies) и фактическими списками (возвращает 'Nil'), поэтому нет. –

+0

Оператор '[]' подробно объясняется [здесь] (https://docs.perl6.org/language/subscripts.html). Он разработан очень универсальным и многоразовым - то, что происходит в случае несуществующих элементов, зависит от объекта, который вы индексируете. – smls

ответ

7

Это особенность Any. От the docs:

Поскольку Perl 6 намеренно смешивает элементы и списки одноэлементные, большинство методов в Any также присутствуют на классе List, и принуждают к List или список подобных типов.

Если вас look at the implementation, вы увидите, что нет никакого фактического принуждения необходимо, как Any обеспечивает AT-POS, и это то, что не выполняется для индексов, отличных от 0.

В отличие от этого, implementation of actual lists терпит неудачу только в случае отрицательные индексы и доходности Nil в противном случае.

Семантически, это не совсем безумно, так как один из способов думать о Nil - это тихий провал, но это действительно непоследовательность. Это может быть по дизайну, так как «изящество» предметов - это просто удобная функция, а не часть собственно интерфейса, и поэтому можно предположить, что она будет шуметь, если неправильно использовать.

Обратите внимание, что Array дает третье поведение, возвращая Any по умолчанию, что можно понять в контексте авто-вивификации.

+0

По-видимому, мыслительный процесс заключается в том, что вы можете использовать возврат из функции в виде списка, и он просто работает (например, '' foo ".elems' возвращает 1). Похоже, что на IRC-канале # perl6 обсуждается лучшее сообщение об ошибке. –

5

Это выглядит, как будто скалярная само по себе является своего рода список одного элемента

Если вы явно применить операцию списка в скаляр он ведет себя, как если бы это был список, содержащий один элемент, который это скалярное значение.

Что я не понимаю о [] операторе.

Индексирования операция по списку (любая структура Positional данных; список представляет собой список, но список не может быть списком) проверяется в соответствии с «формой» Списка в, список «диапазоны индексирования».

Вы можете только объявлять диапазоны индексирования массива.

# Value treated as list shape Indexing range 

'a scalar value'   (1)  0..0   
(0,1,2)     (*)  0..Inf 
my @a      (*)  0..Inf 
my @b[42]     (42) 0..41 

(я немного удивлен списками (например, (0,1,2)), которые имеют неизменную форму, будучи назначена формой (*). Почему бы не (3) (в случае списка из 3 элемента), если является и известным, и неизменным? (Возможно, это не так?))

Смежные вопросы