Вы можете дать чёткие правила, в каких случаях (подобных данному) ставить begin-end ?
В выражениях функцию, возвращающую функцию, нельзя записать с помощью короткого синтаксиса. Надо записывать с помощью длинного.
В типе можно испоользовать тип функции, возвращающей функцию.
Это недостаток нашей грамматики. Может, неустранимый.
А в данном случае что делать:
type
TClass<T, T2> = class
property P: () -> (() -> T, () -> T2) read () -> begin Result := (() -> default(T), () -> default(T2)); end;
end;
begin
end.
? Требуется вернуть кортеж из двух функций.
А вот и нет))) Сначала создаётся новый экземпляр типа System.Tuple
, в конструктор которого передаётся 3 параметра, а потом значения вытягиваются по 1. И это дольше, потому что надо создавать экземпляр и значения оказываются в итоге в куче а не на стеке.
Можно - всегда:
begin
var f:()->byte := ()->
begin
Result := 0;
end;
end.
Нужно - когда без этого не обойтись:
begin
var i:integer;
var f:()->byte := ()->
begin
i += 1;
Result := i;
end;
end.
Ой, я бы повесился)) Или лучше расписал бы как отдельные подпрограммы, вместо того чтоб строить пизанские башни))))
Если честно, я ради интереса спросил, а не для того, чтобы этим пользоваться повседневно. Точнее - развлекаюсь как только могу. И все-таки, почему ругается?
А хотя не, можно сделать без дополнительных подпрограмм. Но надо воспользоваться древней забытой техникой - форматированием своего кода:
type
TClass<T1, T2> = class
property P1: () -> (() -> T1, () -> T2)
read () ->
begin
var f1: ()->T1 := () -> default(T1);
var f2: ()->T2 := () -> default(T2);
Result := (f1, f2);
end;
end;
begin end.
Если бы она была такой древней и такой забытой, то я боюсь представить как бы выглядели бы исходные коды программ.
Ну не знаю, вы то её не использовали)) Вот мне и захотелось повесится, как я увидел что строчка и близко не вмещается в ширину моего монитора)).
Я не всерьез же код писал. Если серьезно, то, странно, что если убрать переменные, то код не компилируется:
type
TClass<T1, T2> = class
property P1: () -> (() -> T1, () -> T2)
read () ->
begin
Result := (() -> default(T1), () -> default(T2));
end;
end;
begin end.
. Причём, выдает:
Program9.pas(8) : Встречено ‘)’, а ожидалось выражение
. Issue делать?
Сделайте issue с формулировкой “неправильная ошибка”. Должно ли компилироваться - это отдельный вопрос. Но если не должно - пусть хоть скажет почему.
Ласковее, я же говорил:
type
TClass<T, T2> = class
property P: () -> (() -> T, () -> T2) read () -> begin Result := new System.Tuple&<() -> T, () -> T2>(() -> default(T), () -> default(T2)); end;
end;
begin
end.
Погодите, но ведь кортежи с синтаксисом (Item1, Item2, …) основаны на System.Tuple<T, T1, …>.
Да, правильно, а точнее на System.Tuple.Create<T, T1, …>
. Но грамматика много ещё где не выдерживает.
Я все-таки сделаю Issue. Разработчики, когда будет время, подправят.
Сделайте issue именно про неправильную ошибку. А моменты где компилятор вообще не справляются - не всегда исправляют.
Нет ну а сократить? Расширенные свойства, к примеру, тут не при чём. Уберите из программы-примера всё что не обязательно.
Вас понял. Подправил.
Почему во втором случае не удается неявно преобразовать integer к byte в кортеже:
type
TA = class
property P: byte read 1;
end;
TB = class
property P: (byte, byte) read (1, 1); // Program9.pas(8) : Нельзя преобразовать тип Tuple<integer,integer> к Tuple<byte,byte>
end;
begin
end.
? Проверил в C# случай, аналогичный второму:
class MainClass
{
public (byte, byte) P => (1, 1);
public static void Main (string[] args)
{
}
}
, компилируется. Это особенность PascalABC.Net, или это ошибка?