2015-08-12 3 views
3

Я играю с Цейлоном, и я пытаюсь создать псевдоним для кортежа. Ниже не работают:Можете ли вы присвоить тип кортежа?

class MyPair(Integer i, Float f) => [i, f]; 
class MyPair(Integer i, Float f) => [Integer, Float](i, f); 
class MyPair(Integer i, Float f) => 
     Tuple<Integer|Float, Integer, Tuple<Float, Float, Empty>>(i, [f]); 
class MyPair(Integer i, Float f) => 
     Tuple<Integer|Float, Integer, Tuple<Integer|Float, Float, Empty>>(i, [f]); 
class MyPair(Integer i, Float f) => 
     Tuple<Integer|Float,Integer,Tuple<Float,Float,Empty>>(i, Tuple<Float,Float,Empty>(f, [])); 

Я получаю ошибку на первых двух вращается вокруг использования скобок:

Incorrect syntax: missing statement-ending ; at [ expecting statement-ending ; 

Есть два отдельных ошибок на второй:

Некоторые вариации из

Alias parameter distance must be assignable to corresponding class parameter rest: Integer is not assignable to [Integer] 

на class MyPair и

Argument must be a parameter reference to distance 

f, [f] или конструкция кортежа.

Есть ли способ сделать это?

+0

Хотя я нашел решение, интересно, есть ли более чистый способ сделать это. – Jeffrey

ответ

4

Да, выражение для экземпляра RHS => в объявлении псевдонима класса в настоящее время крайне ограничено, а не по дизайну, но только потому, что потребуется выполнение дополнительной работы для полной поддержки произвольных выражений-экземпляров в компиляторе backends.

Но то, что я бы на самом деле сейчас было бы использовать обычный тип alias, как это:

alias MyPair => [Integer,Float]; 

И использовать его как это:

MyPair pair = [1, 1.0]; 

Я думаю, что это на самом деле еще чище чем с использованием псевдонима class.

HTH.

+0

Ага, не знал, что это возможно. Мое понимание [тура] (http://ceylon-lang.org/documentation/1.1/tour/typeinference/) привело меня к мысли, что регулярный «псевдоним» может использоваться только с типами пересечений и союзов. – Jeffrey

+0

На самом деле вы можете использовать 'alias' с любым юридическим типом. Разница в том, что вы не можете использовать псевдоним везде, где вы можете использовать псевдоним 'class', в частности, вы не можете использовать его в предложении' extends', и вы не можете использовать его в выражении для создания экземпляра , Но так как в этом случае: 'Tuple' является' final' в любом случае, так что это на самом деле не является дополнительным ограничением, и вы не можете действительно улучшить хороший синтаксис '[x, y]' для создания экземпляра. –

2

После мастерить вокруг немного я наткнулся

class MyPair(Integer i, [Float] f) => 
     Tuple<Integer|Float, Integer, Tuple<Float, Float, Empty>>(i, f); 

, который работает.

2

Не может сделать гораздо лучше, чем ваше решение, но вы можете по крайней мере использовать ярлык для параметра Rest типа:

class Pair([Integer i, [Float] f]) => Tuple<Integer|Float, Integer, [Float]>(i, f);

Вы ограничены здесь, потому что типы параметров вашего псевдонима класса должны соответствовать типы параметров класса, которые вы используете. Если я интерпретирование spec правильно:

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

, то это может работать в последующих версиях:

class Pair(Integer i, Float f) => Tuple<Integer|Float, Integer, [Float]>(i, [f]); 

или может быть даже:

class Pair(Integer i, Float f) => [i, f]; 

Тогда опять же, если ваша цель состоит в том, чтобы destructure кортеж, Цейлон 1,2 позволит вам сделать это прямо:

value [i, f] = [2, 0.5]; 
+0

Спасибо! Моя фактическая цель состояла в том, чтобы сделать что-то вроде 'class Pair (shared Integer i, shared Float f) => [i, f]' для псевдонимов элементов пары с другим именем. Похоже, что это единственный способ добиться успеха с полноценным классом. Я понимаю, что эту функцию будет сложно реализовать вообще (что произойдет, если в кортеле есть атрибут с именем «i» с другим типом?), Но я надеялся на ярлык. – Jeffrey

+0

@Jeffrey Вы уверены, что деструктурирование - это не то, что вы ищете? Возможно, вы могли бы обновить свой вопрос на примере того, как вы будете использовать свой класс 'Pair'. – gdejohn

+0

Разрушение, вероятно, будет работать так же хорошо, за исключением того, что я все еще использую 1.1. – Jeffrey

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