Otázka ne přímo k Rustu. Má smysl použití nečeho jako typ Result i v jiných jazycích? Konkrétně mě osobně zajímá Java, tam se někdy až příliš často vyvolávají vyjímky. Mohl bych tam použít něco podobného, ale zase bych tím vybočil z běžných postupů a ve výsledku bych ten kód pro ostatní možná znečitelnil. Dá se někde o tomto tématu dočíst víc? Díky.
Nějak to teoreticky to samozřejmě jde vždycky. např. v céčku:
struct result {
int val;
const char* error;
}
result div(int a, int b) {
result r;
if (b == 0) {
r.error = "Divide by zero";
} else {
r.error = NULL;
r.val = a / b;
}
return r;
}
result v = div(x, y);
if (v.error)
fprintf(stderr, "%s", v.error);
else
// pracovat s v.val
V Javě bych to nedoporučoval, protože result by musela být třída a návratová hodnota objekt v heapu. Jinými slovy každé volání funkce div() by znamenalo alokaci a zápis do heapu a volací kód by musel systematicky dereferencovat pointer. Žádný benchmark nemám, ale tuším že výsledný overhead by byl dost cítit. Podotýkám že Javou jsem se už dlouho nezabýval, takže nevím, jestli novější verze náhodou už neumožňují vracet jednoduché objekty přes zásobník...
To, že se obdoba dá napsat v C (C++) jsem si myslel už minule u Option.
Ale největší změna tam je, že už překladač (v compile time) v případě Option ohlídá, zda po návratu kontrolujeme všechny možné enum stavy (None v případě Option). Předpokládám (pozor, jen odhad, v článku jsem nenašel explicitní upozornění), že pro Result platí totéž.
Takže zpět k dotazu "Má smysl použití nečeho jako typ Result i v jiných jazycích". Dle mého názoru spíše nemá, pokud by byl použit násilně. Pokud nás neohlídá už compiler, že zpracováváme správnou návratovou hodnotu, začíná násilné použití ztrácet smysl. Stejně by došlo k exception, při chybném užití. Pak už je jedno, zda kontroluji na chybný stav objekt 9na nějako naší definovanou err hodnotu (třeba i nuly, ale i jinou), nebo zda kontroluji pointer na err na NULL.
P.S.: Ten příklad, přepsaný do C, mi připadá špatně. Správně by mělo být struct na bool (zda chyba či platný) a enum. A v enum vyjmenovat ty dvě návratové varianty (error a platná). Error přece nemusí být jen char* (kde jeho NULL asi bereš jako flag není-chyba), opravdu obecná definice potřebuje někde vracet informaci, zde se vrací platný či chybový stav.
Jistě, v tom příkladu jsem předpokládal, že error == NULL znamená není chyba. Je to v podstatě přesný ekvivalent autorova příkladu v Rustu s Result<i32, &'static str>. Obecná definice to samozřejmě není, jenomže C bohužel nemá generické typy, takže pro skutečně správnou obecnou definici by bylo třeba nasadit makra a už by to začalo být veselé. Překladač samozřejmě nic nehlídá, ale jsme v C, kde se všechno dělá ručně, takže v zásadě by to zůstalo idiomatické. Respektive to není o nic horší, než skutečnost, že nám překladač taky negarantuje, že pointer není NULL nebo že se při strcpy řetězec opravdu vejde do destinace.
Nejprve omluva, měl jsem mít "union" místo "enum".
Obecná definice by byla celkem pohodová pro C++ (template) a alespoň částečně by hlídala typy.
Jinak si asi rozumíme. Chtěl jsem jen vypíchnout pointu, že v jazycích, které nezařvou už v compile time, nemá taková konstrukce smysl, pokud err stavy dokážeme nenásilně předávat už nyní (specifickou hodnotou, např tím NULL u pointerů). Při (zapomenuté) neošetřené chybě to následně v runtime padne tak jako tak.
"Předpokládám (pozor, jen odhad, v článku jsem nenašel explicitní upozornění), že pro Result platí totéž."
o tom je tato kapitola ne? https://www.root.cz/clanky/reakce-na-chyby-v-programovacim-jazyku-rust/#k07
To odkazované popisuje konkrétní chování u match. Pro odchovance C/C++ mi to (chybně) připadalo jen jako trochu jiné switch.
Ale minule bylo, v komentářích zmíněno, jestli dobře chápu, že Option varuje obecně kdykoli. Např. https://www.root.cz/clanky/datovy-typ-option-v-programovacim-jazyku-rust/nazory/909944/ Kontrola je třeba i při "if", ne jen u zde zmiňované "match".
Jestli dobře chápu, překladač hlídá, že programátor musí (alespoň jednou) v kódu udělat (nějakou, libovolnou) kontrolu null výsledku. A právě předpokládám, že pro Result bude platit totéž pro Err.
Eh, ten nadpis je poněkud zavádějící: Pod "Reakce na chyby v programovacím jazyku Rust" jsem čekal článek, který popisuje reakce lidí, ev. tvůrců jazyka na nějaké objevené chyby v Rustu.
Co spíš "Ošetřování chyb v programovacím jazyku Rust" nebo aspoň "Programovací jazyk Rust: Reakce na chyby", pokud tam nutně musejí být ty reakce?