Является ли приведение массива к строке «особенным» среди других типов? - PullRequest
3 голосов
/ 24 января 2020

В этом коде я преобразую целочисленный массив arr в несколько различных типов. При приведении к real результатом является массив, полученный путем приведения каждого элемента к real. И то же самое происходит для complex. Но если я приведу arr к string, результатом станет скалярная переменная string. Это было немного удивительно для меня, потому что я первоначально ожидал массив строк ...

var arr = [1,2,3];
writeln( arr );
writeln( arr.type:string );

var r = arr : real;
writeln( r );
writeln( r.type:string );

var z = arr : complex;
writeln( z );
writeln( z.type:string );

var s = arr : string;
writeln( s );
writeln( s.type:string );

(Результат с chpl-1.20)

1.0 2.0 3.0
[domain(1,int(64),false)] real(64)
1.0 + 0.0i 2.0 + 0.0i 3.0 + 0.0i
[domain(1,int(64),false)] complex(128)
1 2 3
string

Однако, поскольку строка используется в Ввод / вывод (например, writeln(arr)), я предполагаю, что приведение к строке может быть «исключительным» или «специальным» среди других типов. Если да, то разумно ли предположить, что arr : T всегда дает новый массив типа элемента T, если T не string и доступно преобразование каждого элемента в T?

1 Ответ

2 голосов
/ 24 января 2020

Я думаю, что ваши предположения верны. Когда массив приводится к типу string, получается единственное строковое значение, потому что (a) можно представить массив в виде строки, (b) это приведение поддерживается и (c), как вы заметили, нам нужно эта возможность для таких вещей, как ввод / вывод. Это справедливо для большинства типов, поэтому правило, которое «выигрывает» в этом случае, - «выражения произвольных типов обычно поддерживают приведение к строке в часовне».

В отличие от этого, когда массив int приведен к real (скажем), нет никакого определения, определенного из массивов в вещественные числа. Однако существует преобразование, определенное от int до real, поэтому правила продвижения массива Chapel вступают в силу, и приведение применяется к каждому элементу массива параллельно. Фактически, выражение arr: real переписывается как [e in arr] e: real.

. Это также предлагает способ, которым вы могли бы получить массив строковых результатов, если это то, что вы хотели для конкретного случая c: итерация по массив, приводящий каждый элемент к строке ( TIO ):

var arr = [1,2,3];
writeln( arr );
writeln( arr.type:string );

var s = [e in arr] e:string;
writeln( s );
writeln( s.type:string );

(и эта форма должна работать одинаково для любого допустимого приведения типа элемента, это просто немного больше, чем печатать, чем сокращение, которое позволяет продвижение, но в общем случае c это может быть уместно).

...