Jak rozumiecie enumy z typem?

0

Cześć
patrzę się na RUST i ciekawi mnie jak rozumiecie enumy z typami

taki zwykły enum to ALTERNATYWA - albo to albo tamto

enum color {
 Red,
 Blue,
 Green
}

a taki enum

enum location {
  Street(String),
  Number(u16),
  ZipCode(Zip_Format),
  Unknown
}

przypomina mi opis obiektu z dodatkowym stanem gdy lokacja nie jest znana

to nie jest alternatywa - to jakby takie struct+ (bo ma to Unknown), ale z drugiej strony te atrybuty lokalizacji nie są wspólne

jak Wy to rozumiecie?

11

To jest po prostu "union type" (suma typów) - czyli faktycznie alternatywa :-)
Występuje to w wielu jezykach https://www.tutorialsteacher.com/typescript/typescript-union
w niektórych dziwnie (np. w dawnej javie można to było robić przez dziedziczenie, obecnie da się przez "sealed class" (które to sealed nie ma nic wspólnego z sealed w C# o ile wiem)).

Przy czym ten przykład z enum location to chyba jeden z bardziej bezsensownych.
Albo nie wiadomo, albo ktoś mieszka na ulicy, albo pod numerem, albo ma kod pocztowy, serio?

0
jarekr000000 napisał(a):

To jest po prostu "union type" (suma typów) - czyli faktycznie alternatywa :-)
Występuje to w wielu jezykach https://www.tutorialsteacher.com/typescript/typescript-union
w niektórych dziwnie (np. w dawnej javie można to było robić przez dziedziczenie, obecnie da się przez "sealed class" (które to sealed nie ma nic wspólnego z sealed w C# o ile wiem)).

dzięki za odpowiedź
szukam jakiegoś use case dla takiego enuma
może za bardzo mam zabetonowaną głowę "starymi" językami
ale średnio widzę

np adres IP

enum IP {
 v4(string),
 v6(string),
 None
}

to mi przychodzi do głowy
ale dużo takich dwustanowych rzeczy się robi

enum Enumek {
  something(sth type like address, person, itd),
  None//or unknown
}

co można opędzić generykiem

ale to się z tego taki OPTION już robi coś jest albo nie ma

co do enum Location
to przykład jakiegoś gościa (YT) co tłumaczył enumy w RUST - ja tego zwyczajnie nie poczułem, dlatego pozwoliłem sobie spytać
bo być może jest tak, że ja czegoś nie rozumiem a rustowiec chwyta w lot :)

6

Taki enum to po prostu zwykłe modelowanie domeny, konstruowanie nowych typów
Bardzo podobne do modelowania obiektowego tylko po prostu uporządkowane matematycznie.

Żeby skonstruować dowolny typ potrzebujesz:

  • typów podstawowych (Int, String, Float)
  • iloczyn (aka rekord) - czyli twój typ wynikowy to coś co ma po kolei wszystko wymienione w rekordzie
 Home {
        street: String,
        number: u16,
        city: String,
        zip_code: String,
    },
  • unia (czyli w rust enum) - twój typ wynikowy to jeden z zadanych typów (alternatywa):
enum AddressKind {
 Home, Work, POBox 
}

A potem to kombinujesz i możesz wszystko :-)

enum Address {
    Home {
        street: String,
        number: u16,
        city: String,
        zip_code: String,
    },
    Work {
        street: String,
        city: String,
        zip_code: String,
    },
    POBox {
        number: String,
        city: String,
        zip_code: String,
    },
    Other(String), // by ChatGPT
}

Jak dostałeś taki przykład enum location to nie dziwne, że Cię zamotało - trudno o bardziej mętny przykład.

0
jarekr000000 napisał(a):

taki enum to po prostu zwykłe modelowanie domeny,

o widzisz
i teraz już rozumiem

dziękuję bardzo
po prostu przykład mi w głowie namieszał, że czegoś nie rozumiem,nie ogarniam, ale mi wyjaśniłeś

4
jarekr000000 napisał(a):

Albo nie wiadomo, albo ktoś mieszka na ulicy, albo pod numerem, albo ma kod pocztowy, serio?

Tak, ten koleś się nazywał Erwin Schrödinger.

0
somekind napisał(a):
jarekr000000 napisał(a):

Albo nie wiadomo, albo ktoś mieszka na ulicy, albo pod numerem, albo ma kod pocztowy, serio?

Tak, ten koleś się nazywał Erwin Schrödinger.

To ten koleś od kodu Schrödingera? U niego działa, na produkcji nie?

1

Nie, to się wtedy nazywa SOA.

1
somekind napisał(a):
jarekr000000 napisał(a):

Albo nie wiadomo, albo ktoś mieszka na ulicy, albo pod numerem, albo ma kod pocztowy, serio?

Tak, ten koleś się nazywał Erwin Schrödinger.

Heisenberg miał gorzej - jak sprawdzał prędkościomierz to kompletnie gubił gdzie się znajduje. A w jego czasach nie było GPSów.
Rypane enumy.

1

które to sealed nie ma nic wspólnego z sealed w C# o ile wiem - sealed w javie działa podobnie jak sealed w scali, a c#owe sealed (przynajmniej takie gołe) działa podobnie jak final class z javy czy scali. oczywiście nie są to dokładne charakteryzacje i można się czepiać, ale nie chce mi się teraz przypominać szczegółów.

2

słowa kluczowe to jedno, a ich semantyka to drugie. sugeruję nie analizować zbyt głęboko słów kluczowych (w sensie ich nazw), bo te często dobierane są tak, żeby były krótkie i znajome, a nie precyzyjne i dokładne.

mussel napisał(a):
enum location {
  Street(String),
  Number(u16),
  ZipCode(Zip_Format),
  Unknown
}

to jest https://en.wikipedia.org/wiki/Tagged_union (uwaga: przez obecność tagu nie jest to zwykłe union, w przeciwieństwie do tego co napisał @jarekr000000 :] ). w językach obiektowych tag można emulować za pomocą klas i tak robi np. scala (ale też java i inne).

mussel napisał(a):
enum color {
 Red,
 Blue,
 Green
}

to jest https://en.wikipedia.org/wiki/Enumerated_type

An enumerated type can be seen as a degenerate tagged union of unit type.

2

To jest po prostu ładniejsza wersja unii w C. W C przeważnie i tak trzeba połączyć unię z jakimś typem wyliczeniowym, który mówi jak zinterpretować zawartość. Tu mamy to połączone w jedno, ładnie obsługiwane przez kompilator. Można tego użyć albo do obsługi różnych wariantów z różnymi interfejsami albo jako alternatywę dla traitu, która nie wymaga ani dyna ani typu z parametrem, co pozwala oszczędzić sporo zabawy w niektórych przypadkach. Wciąż można tego też użyć jako zwykły enum. Bardzo fajna rzecz.

2

jeszcze jeden głupi przykład:

enum Expression {
    Literal(i32),
    BinaryOp(Operator, Expression, Expression),
    UnaryOp(Operator, Expression),
}
impl Expression {
    fn eval(&self) -> i32 {
        match &self {
            Literal(x) => x,
            BinaryOp(op, e1, e2) => op.eval(e1.eval(), e2.eval()),
            UnaryOp(op, e) => op.eval(e.eval()),
        }
    }
}
0
mussel napisał(a):

to nie jest alternatywa - to jakby takie struct+ (bo ma to Unknown), ale z drugiej strony te atrybuty lokalizacji nie są wspólne
jak Wy to rozumiecie?

Ja robię w Swifcie więc nie rozumiem ale tak z boku to przypomina structy z funkcjami w C.

1
loza_prowizoryczna napisał(a):
mussel napisał(a):

Ja robię w Swifcie więc nie rozumiem ale tak z boku to przypomina structy z funkcjami w C.

Przecież Swift ma to samo, tylko z lekko zmienioną składnią:

enum Foo {
  case a(String)
  case b(Int)
}
0
hauleth napisał(a):

Przecież Swift ma to samo, tylko z lekko zmienioną składnią:

O nie, to nie jest enum z typami to jest enum with associated values. Mała różnica a dużo zmienia bo np. do tej pory nie można stworzyć enuma z generykami :(

2

Enum z generykami? czy to już GADT jak w Scali 3?

enum Size:
  case Empty
  case NonEmpty

enum SafeList[+A, +S <: Size]:
  case Nil extends SafeList[Nothing, Size.Empty.type] // <-
  case Cons(head: A, tail: SafeList[A, Size]) extends SafeList[A, Size.NonEmpty.type]
0

Brak przykładów użycia

Przypadkiem użycia jest nazwa GADT pod mią możesz sprawdzić co to

1 użytkowników online, w tym zalogowanych: 0, gości: 1