И так, что же у нас нового… В примерах в коммите есть вот что:
begin
var a := Arr(1, 9, 8, 7, 2, 3, 4, 5);
// Расширенный is
if a is [1, .., var x, _, 5] then
Println(x);
// match .. with
match a with
[1, 9, 8, _, 2]: print(1);
[.., var y, var x]: print(x + y);
[_, .., _]: print(3);
end;
end.
_
, похоже, значит что не важно какой там элемент.
..
- а это явно пропуск нескольких элементов.
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
public
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var p1 := new Person('Вася', 11, new CardInfo('12345671', 321));
var p2 := new Person('Петя', 12, new CardInfo('12345672', 322));
var p3 := new Person('Маша', 13, new CardInfo('12345673', 323));
var personArr := Arr(p1, p2, p3);
// Расширенный is
if personArr is [Person(name1, 11, CardInfo(_, cv)), _, Person(name2, 13, _)] then
println(name1, cv, name2);
// match .. with
match personArr with
[_, _, Person('Вася', age, _)]: print(age);
[var p, .., Person('Маша', _, _)]: print((p as Person).name);
[..]: print(1);
end;
end.
Значит, так же, известно что алгоритм рекурсивный, и работает для полей элементов которые были обработаны.
Дальше ещё видно что в классе Person
могут быть поля, для которых тоже можно применить Pattern Matching вида []
.
+ я ещё покопался в самом коде коммита, и там явно видно, алгоритм таки рекурсивный.
Первый вопрос:
Почему print((p as Person).name);
, а не print(p.name);
? Уже ведь известно что p
это Person
. Если это какое то ограничение - почему? Или же это просто пример такой, можно и print(p.name);
писать?
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
name: string;
age: integer;
card: List<CardInfo> := new List<CardInfo>();
constructor(name: string; age: integer; card: List<CardInfo>);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: List<CardInfo>);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var cards := new List<CardInfo>();
cards.Add(new CardInfo('12345671', 321));
cards.Add(new CardInfo('12345672', 322));
cards.Add(new CardInfo('12345673', 323));
cards.Add(new CardInfo('12345674', 324));
var p := new Person('Вася', 21, cards);
// match .. with
match p with
Person('Петя', _, _): print('Петя');
Person('Вася', _, [_, _, var x]): print(x);
Person(name, _, [CardInfo(_, 321), .., CardInfo(_, 324)]): print(name);
end;
end.
А вот и []
внутри другого деконструктора, содержащий ещё 1 деконструктор внутри.
begin
var a := 3.14;
match a with
1.0, 2.0, 3.0: Println(1);
3.13, 3.14, 3.15, 3.16: print(2);
123.0: print(3);
end;
end.
case
здорового человека)))
Вот только прямое сравнение на равенство 2 значений типа real
напрягает, так же нельзя делать!
Можно как то так сделать?:
begin
var a := 3.14;
match a with
3.13..3.15: print(1);
else print(2);
end;
end.
Второй вопрос:
@Admin вы вроде ещё когда то говорили про такой синтаксис, ещё до того как первый паттерн мачинг был сделан:
begin
var a := 3.14;
var res := match a with
1.0, 2.0, 3.0: 1;
3.13, 3.14, 3.15, 3.16: 2;
123.0: 3;
end;
res.Println;
end.
Что насчёт этого? Стоит ли ещё ждать, или может оно уже работает с этим коммитом?
begin
match (1, 2, 'string') with
(1, _, var x): Println(x);
(1, _, 'strin'): print(2);
(_, _, 'string'): print(3);
end;
end.
Деструктор кортежа… Ну, я бы удивился если бы его небыло))
type
CardInfo = auto class
public
cardNumber: string;
cv: integer;
end;
Person = class
name: string;
age: integer;
card: CardInfo;
constructor(name: string; age: integer; card: CardInfo);
begin
self.name := name;
self.age := age;
self.card := card;
end;
procedure Deconstruct(var name: string; var age: integer; var card: CardInfo);
begin
name := self.name;
age := self.age;
card := self.card;
end;
end;
begin
var a := new Person('Вася', 11, new CardInfo('12345678', 324));
// Расширенный is
if a is Person(_, var age, CardInfo(_, var cv)) then Println(age, cv);
// match .. with
match a with
Person('Петя', 12, CardInfo('12345678', var cv)): Println(cv);
Person('Вася', _, CardInfo(cardNum, 324)): Println(cardNum);
Person(_, _, CardInfo(_, x)): Println(x);
end;
end.
Конечно, для is-var
это всё тоже пашет.
И 1 интересный код из тестов:
begin
var a := Arr(1, 9, 8, 7, 2, 3, 4, 5);
var c: procedure := () -> begin
match a with
[.., 4, var x]: assert(x = 5);
end;
end;
c;
end.
Вау, match
дружащий с лямбдами!
Правда, тест то плохой, ибо если по какой либо причине match
в лямбде будет заменятся чем то что никогда не выполняется - assert(false)
никогда не произойдёт и тест пройдёт успешно. Лучше сделать так:
begin
var a := Arr(1, 9, 8, 7, 2, 3, 4, 5);
var res := 0;
var c: procedure := () -> begin
match a with
[.., 4, var x]:
begin
assert(x = 5);
res := 1;
end;
end;
end;
c;
assert(res = 1);
end.