V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.
Oficiální ceny Raspberry Pi Compute Modulů 4 klesly o 5 dolarů (4 GB varianty), respektive o 10 dolarů (8 GB varianty).
Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.
Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.
Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.
Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.
Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.
Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.
Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Kdyz vidim zase po nejake dobe kod v C tak uz vim proc mam rad D :D
import std.stdio; import std.range; import std.algorithm; import std.conv; List!T list(T)(T[] data) { return new List!T(data); } class List(Type) { Type value; List!Type next; this() {} this(Range)(Range data) if (isInputRange!Range && is(Type : ElementType!Range)) { auto current = this; current.value = data.front; foreach (value; data.dropOne) { current = current.next = new List(value); } } this(Range)(Range data) if (isInputRange!Range && !is(Type : ElementType!Range)) { this(data.map!(a=>to!Type(a))); } this(Type value) { this.value = value; } @property Type[] values() { Type[] values; foreach (v;this) values ~= v; return values; } @property auto end() { auto current = this; while (current.next !is null) current = current.next; return current; } List!Type opBinary(string op)(List!Type list) if (op == "~") { end.next = list; return this; } List!Type opBinary(string op, OtherType)(List!OtherType list) if (op == "~" && !is(Type == OtherType)) { auto l = new List!Type(list.values); return opBinary!op(l); } auto ref opUnary(string op)() if (op == "++") { return next; } void remove(Type value) { auto current = new List!Type(); current.next = this; while (!(current is null || current.next is null)) { if (current.next.value == value) current.next = current.next.next; else current = current.next; } } int opApply(int delegate(ref Type) dg) { int result = 0; List current = this; while (current !is null) { result = dg(current.value); if (result) break; current = ++current; } return result; } } void main(string[] args) { auto l = list([10, 12, 7, 18, 4, 6]); foreach (v;l) writeln(v); auto l2 = list(["10", "12", "7", "18", "4", "6"]); foreach (v;l2) writeln(v); auto l3 = l ~ l2; foreach (v;l3) writeln(v); }
void create(struct list **list) { struct list *link; int val; printf("Zadejte cisla a ukoncete znakem:\n"); while (scanf("%d", &val) == 1) { *list = link = malloc(sizeof(struct list)); if (!link) exit(1); link->val = val; link->next = NULL; list = &link->next; } while (getchar() != '\n') ; }Jinak v C nemusíš přetypovávat void*.
void append(struct list **list) { struct list *l2; create(&l2); while (*list) list = &(*list)->next; *list = l2; }
Tak ono hlavni problem v tvem kodu jsou nazvy (ale to jsem ochotnej akceptovat pokud jde jen o ukazku nebo o datovou strukturu ktera bude nekde schovana a nebude se na ni sahat), ale jako mnohem vetsi
problem vidim to ze v metode pro spojovani seznamu (metoda a) vytvaris pole (volani metody c), to je asi to nejhorsi co programator muze udelat. Jiank dobry programator s tebe byt urcite za par let muze. Pokud k tomu ma clovek vlohy a chut zlepsovat se, tak nevidim duvod proc by to nemelo jit.
typedef struct ... { ... } list;Záleží na zvyklostech, ale pokud už se to musí jmenovat list, dal bych přednost struct list. Pokud to musí být nutně typedef, tak použít nějakou konvenci, aby list zůstalo volné. Tedy...
struct list { int data; /* V reálné implementaci spíše typ 'void *'. */ struct list *next; }Vytvoření seznamu
c(list **l)Funkce by neměla dělat žádné IO operace, tedy žádný
printf
ani scanf
a její prototyp by měl být navržen účelně. U seznamu s hlavou dává smysl:
list_init(struct list *head)Nebo:
struct list *list_new(void)V případě seznamu bez hlavy nemá inicializace smysl a stačí používat:
struct list *list = NULLZrušení seznamu
void f(list *l)Doporučuju dávat hned pod vytvoření, původně jsem si myslel, že chybí. Volající je zodpovědný za ukončení používání hodnoty pointeru. Tomu se dá v případě zájmu vyhnout:
void list_clear(struct list **list)Připojení dalšího seznamu Zcela nesmyslné ač pokročilé API, které nedělá nic, co by bylo k něčemu dobré. Odstranění prvku dle hodnoty Pokročilá funkce, která se občas hodí, API v celku dává smysl, ale chybová hláška je zbytečná. Pokud je opravdu potřeba vracet informaci o počtu smazaných prvků, je lepší použít návratovou hodnotu.
int list_delete_all(struct list **list, int value)Může dávat smysl i funkce pro smazání jednoho:
bool list_delete_one(struct list **list, int value)(Lze samozřejmě použít opět typ
int
.)
Debugovací výpis
void p(list *l)Dává smysl. Co chybí? Jenom namátkou.
/* Přidej na začátek. */ void list_push(struct list **list, int data); /* Odeber ze začátku, v reálné implementaci návratový typ 'void *'. */ int list_pop(struct list **list); /* Bez obrácení se s jednosměrným seznamem špatně pracuje. */ void list_reverse(list **list);Proč obousměrný seznam Jednosměrný spojový seznam je vskutku debilní datová struktura vhodná k jednoduchým operacím typu push/pop na začátku seznamu a operacím, které iterují nad celým seznamem. Dvousměrný spojový seznam, ideálně s hlavou, oproti tomu nabízí možnost vytvořit velice příjemné a jednoduše implementovatelné API:
struct list { int data; /* Ve reálu 'void *'. */ struct list *previous; struct list *next; }; void list_init(struct list *head); void list_clear(struct list *head); /* Nebo dynamicky: * struct list *list_new(void); * void list_free(struct list *head); * void list_clear(struct list **head); */ /* Přidat před/za libovolný prvek. Vložení za hlavu znamená na začátek, před hlavu znamená na konec. */ void list_add_before(struct list *item, int data); void list_add_after(struct list *item, int data); /* Odstranění libovolného prvku. */ int list_remove(struct list *item); /* Zkratka pro vložení na začátek/konec. */ #define list_insert(head, data) list_add_after(head, data) #define list_append(head, data) list_add_before(head, data) /* A další */Na konec... Uhlazené API by pak rozlišovalo objekt, který reprezentuje celý seznam a objekty, které reprezentují jednotlivé prvky a případně by poskytovalo callback API pro uvolňování dat a podobné věcičky.
Datove struktury se samzrejme pouzivaji, ale u vetsiny jazyku uz jsou predpripravene a nemusis si je sam tvorit. Napriklad pro c++ http://www.cplusplus.com/reference/stl/. Jinak doporucuji zacit jen jednim jazykem, ackoliv C a C++ se da ucit naraz, tak je dobre ze zacatku pochopit jen jedno paradigma a pak az druhe. Pokud budes od zacatku mixovat proceduralni a OOP tak se v tom muzes zamotat.
BTW. Proc C++? To bych nedoporucoval, neni to zrovna idealni jazyk na kterem by si mel IMHO zacinat.
Tak Qt mohu vrele doporucit je to velmi fajn toolkit nejen pro tvorbu UI. Jinak sam jsem v nem kdysi pracoval a v QtCreatoru to s C++ nebylo vubec tak zle. Ale s porovnanim s kombinaci napriklad pyqt (Python + Qt) to bylo furt takove zbytecne slozite.
Jinak dva roky s prestavkami to zase neni tak dlouho. Ja uz programuji od 12 let mozna drive a ted mi je 25, to znamena polovinu sveho zivota a stale si dovolim tvrdit ze se ohledne programovani mam co ucit.
$> python2 some-code-written-in-python2.py
Takže v čem je problém?
for
platí jen uvnitř cyklu, nebo až do konce bloku. Standard to pořádně nedefinoval, tak to každý překladač dělal po svém.
Od C99 se už kompatibilita Céčka bere dost vážně (u C++ je to nejspíš podobné, ale nepovažuji se za znalce normy), u čehokoliv staršího je problematická.
Klíčové slovo auto existovalo i u K & R. A také fungovalo stejně jako v ANSI C. Kdo znal standard, nemohl mít problémy.Pardon, už zapomínám. Není to
auto
, nýbrž const
. To v K&R není a až ANSI C ho zavádí.
unsigned
tam bylo, signed
nikoliv.
Napriklad pro c++ http://www.cplusplus.com/reference/stl/.Doporučil bych spíš cppreference.com, imho kvalitnější. Jinak +1 k tomu C++: Pokud si tazatel nepřipadá jako zdatný programátor a/nebo nemá OOP v malíku, určitě by bylo lepší začít s něčím jiným než C++. Např. ten python, object pascal a podobně. (To říkám na základě vlastní zkušenosti: můj první progam v C++ byla hrozná obludná příšerná prasečina
Před chvílí jsi zmiňoval python, ale Java je podle tebe fuj kvůli gc?
Tak tady bych nesouhlasil. Ne kvuli Jave. Tu sam moc nedoporucuji. Ale kvuli duvodu ze o pamet se neni potreba starat. Prave ze pro zacatek je fajn mit jazyk kde to neni potreba. Pokud ten jazyk ma spravu pameti resenou solidne tak nebyva problem. Napriklad me se velmi libi jazyk D. Viz ma ukazka vyse. Nikde tam neresim uvolnovani pameti a obecne ja pametova narocnost cca 3x vetsi nez u manualni spravy. Ano muze se to zdat dost ale v dnesni dobe to vubec nebyva zas takovy problem.
Jinak Java vs. D. Tak D je mnohem jednodusi. Teda aspon pro me bylo peklo snazit se psat v Jave potom co jsem si navykl na jazyky jako python a D.
Prave ze pro zacatek je fajn mit jazyk kde to neni potreba.Tahle poučka se hodně často opakuje, ale mě přijde, že to není moc opodstatněný. Pro opravdu úplného úplného začátečníka to asi je lepší, ale jakmile začne mít někdo ambice psát algoritmy, struktury a případně užitečné programy, měl by k nějakým základům memory managementu přičichnout (IMHO).
Pokud programuje v Jave uz bude umet dynamickou alokaci a mazani uz neni takovy problem.To je otázka. Já bych spíš sázel na to, že začátečník ti řekne "Nó, tady si dám
new Foo()
a tím si udělám novej objekt" a pojmy jako dynamická alokace/dealokace nebo heap mu nic neřeknou.
Suma sumárum, IMHO programovat v Javě dobře je ve výsledku úplně stejně náročné jako v ostatních jazycích...
Někteří měli plnou hlavu dizajn patternů, ale přitom mezery v základech programování.Tož bylo by fajn říct, co ty základy programování jsou - zajímalo by to mě a zřejmě i tazatele. Jonak celé programování je o dizajn patternech, ne? Akorát na různých úrovních.
Tož bylo by fajn říct, co ty základy programování jsou - zajímalo by to mě a zřejmě i tazatele.Jeden začátečník na jednom projektu asi před 2 lety střemhlav aplikoval několik "dizajn patternů" (byly tam nějaký singletony a nějaký factory nebo co to tehdá bylo), ale přitom v návrhu tý aplikace byly zcela elementární chyby, jako např. GUI načítalo data stále znova z disku a ze sítě a ignorovalo, že data už byly načtený a připravený k zobrazení o vrstvu níž apod. Ten dotyčný ani pořádně nevěděl, co ten program dělá, měl v tom naprostej guláš, ale když jsem ho konfrontoval, tvrdil, že "takhle se to dělá". A to jsem přitom na něj ani nebylo nějak zlej nebo něco
Jinak celé programování je o dizajn patternech, ne? Akorát na různých úrovních.Tak v zásadě se za disajn pattern asi dá označit ledacos. Já nejsem nějak zásadně proti, znát best practices je určitě dobrá věc, ale na dizajn patternech (zejména na jejich výuce) se mi nelíbí to, že svádí lidi (zejména začátečníky) k tomu, aby kopírovali nějaký postup, aniž by věděli, proč je dobrý ten problém řešit zrovna tím způsobem, nebo dokonce v horším případě aniž by vůbec věděli, co daný kód znamená/dělá.
Tak ona i ta definice glue language je v tomhle pripade ucelove priohunta. Ono se tim mysli jazyky spojujici hotove kusy kodu. Tedy, ze clovek vic lepi existujici reseni, nez ze vymysli reseni vlastni. V tom se ale C, Java ani C++ diametralne nelisi. Proste se saha do standardnich knihoven, ktere poskytuji +/- to same (i kdyz v tom C spis -).
Jazyk v jakem jsou jednotlive komponenty napsany je z hlediska definice "glue language" naprosto nepodstatne.
Takze v momente, kdy nekdo postavi HW JVM, tak se Java stane samonosnou? Jednoduse samonosny muze byt jedine takovy jazyk, ktery umi volat funkce OS. A pokud se podivame treba na glibc, tak ty casti v asm asi taky nejsou z hlediska samonosnosti ok. Takze samonosnost je takova pekna akademicka vlastnost, ale z hlediska hodnoceni kvalit jazyka naprosto nesmyslna.
Jinymy slovy Java je fuj, protoze preklada do bytecodu, zatimco C++ je fajn, protoze preklada do strojaku?
Ja spis ocekaval odpoved na to, kde je ten podstatny rozdil v moznostech jazyka. Jake jazykove konstrukce nahrazuji v C++ to lepeni knihoven, ktere vidite v Jave.
Imho by ten asm slo eliminovat i prakticky, zas tolik ho neni. Navic jsou to casto platforme zavisle casti kodu. Hodne ho je, jak se zda okolo fpu, takze by se ztratila nebo zpomalila nejaka funkcionalita.
Ale asi tezko bez asm napiste program pro nejakej jednocip, na kterem nebezi OS, nebot tu incializace HW, kterou za vas jinak provede OS (a ktera je z casti v asm), si musite pridat primo do vaseho programu.
Jonak celé programování je o dizajn patternech, ne?Tím bys z programování vyloučil používání mozku (k něčemu jinému než paměti) a tvůrčí činnost.
Zaprvé, single-linked listy se hodí opravdu jen na velmi omezené množství úloh. Zadruhé, implementace, kdy je zadrátovaný napevno typ prvku má velmi omezené použití. Zatřetí, v normálních prostředích (POSIX) je již podpora listů v C-knihovně standardně k dispozici #include <sys/queue.h>. A nakonec začtvrté, určitě je velmi užitečné si implementaci zkusit napsat sám, aby člověk pochopil, co je dobré a jaké vlastnosti od různých jiných implementací čekat.
Odkazy na standardní lib-C manuélovou stránku man QUEUE, man TAILQ_INSERT_TAIL, ...
V době , kdy jsem podobné konstrukce potřeboval opakovaně řešit a to především na embedded systémech, tak ještě standardně tato implementace nebyla k dispozici. Takže jsem si napsal vlastní implementaci listů (základní struktura pro kompatibility převzatá z jádra), stromů a dalších podpůrných algoritmů. Řešení pro verzi s vygenerovanými custom inline funkcemi zajišťuje typovou bezpečnost / relační příslušnost prvek list. Ale je to docela makro-magie. Knihovna uLUt - uLan/Universal Light Utilities Library je k dispozici je včetně dokumentace na stránce projektu http://ulan.sourceforge.net. Na pochopení je implementace dost náročná, díky nutnosti použití maker není dobře čitelná, ale optimalizuje se dobře a lze jí přeložit od 8-bit systémů (když zrovna není v SDCC chyba tak i tím) až po 64-bitů - Linux, RTEMS, Windows, bez systému, x86, ARM, m68k, msp430 a je již používaná v množství průmyslově využitých aplikací.
Zatřetí, v normálních prostředích (POSIX) je již podpora listů v C-knihovně standardně k dispozici sys/queue.hTo vypadá docela děsivě, ale to je s části tou hrou s makry a z části těmi prvními dvěma z mého pohledu redundantními implementacemi.
Máte pravdu, že to sys/queue.h je (zatím) jen BSD rozšíření, ale před nedávnem jsem viděl něco v diskuzi o Newlib nebo jinde, kde o požadavcích standardu na implementaci front diskutovali a nedal jsem si dostatek práce dohledat, jestli to již je ve standardu a nebo jsem si to spletl.
V každém případě POSIX nebo spíš IEEE Std 1003.1-2001 již nějaké fronty a hashe jako povinné definuje.
http://pubs.opengroup.org/onlinepubs/009696799/functions/remque.htmlJinak zajímavým zdrojem algoritmů pro psaní programů v C, který také listy a vyšší datové struktury obsahuje, je Rusty Russell's CCAN (C Code Archive Network) http://ccodearchive.net/index.html.
Dále menším takovým repository je libUCW http://www.ucw.cz/libucw/, kterou udržují lidé z Matfyzu. Pro některá embedded zařízení je ale problém LGPL.
Bez maker nebo templátů nebo dědičnosti to nelze v C/C++ napsat tak, aby to hlídalo proti sobě typy vkládaných prvků a hlavy listu. Přitom nabídnutí uživateli funkcí s void* jako doporučeného API je cesta k výjimečnému hrobu. takže z tohoto pohledu tu verzi z standardu považuji bez wrapperu jako mnohem horší. Také počítat s tím, že struktura musí mít fieldy v pořadí, jak je deklarovaná a na začátku že uživatel vloží dva ukazatele nebo strukturu s nimi je opět náchylné k chybám, které se zavlečou nesouvisející úpravou v kódu. Přitom často je výhodné mít ve struktuře položky/uzly pro řazení do více nezávislých seznamů. Takže i jen kontrola na strukturu nodu, tak jak je to v jádře Linuxu, může vést k fatálním chybám.
Mnou používané řešení v uLUt veškeré tyto chyby odchytne, ale chybové hlášky jsou dost nepřehledné.
Asi nejelegantnější řešení typové kontroly v případě implementace v C jsem viděl v následující sérii patchů pro Red-Black stromy používané v Linuxovém jádru http://thread.gmane.org/gmane.linux.kernel/1367138/focus=1367138
Na rozdíl od uLUt je mnohem více implemetace realizováno v inline funkcích, kterým se předává popisová struktura vkládaných typů. Type safe funkce stejně nakonec vyžadují jejich generování makrem, ale je to mnohem přehlednější. Na druhou stranu je to řešení, které je mnohem více závislé na kvalitách kompilátoru. Novější verze GCC ale dokáží overhead kódu (popisu problému) zredukovat na přímočarou implementaci shodnou s použitím kódu bez typové kontroly a s optimalizovanými voláními základních vyvažovacích funkcí přímo v místech vkládání a výběru prvků. Bohužel se toto řešení zatím do jádra nedostalo. Spíš kvůli strachu z velmi starých kompilátorů používaných pro některé architektury. Ale řešení je to pěkné, ideu by z něj bylo dobré reimplementovat nad nějakým jiným základem Red-Black stromů, protože ty z jádra jsou licenčně jen GPL2only.
O reimplementaci tohoto řešení byl zájem v komunitě RTEMSu, ale nebyl zatím dostatek sil. Mohla by to být celkem pěkná semestrálka, pokud by se někdo přihlásil. Třeba v rámci našeho předmětu Open-Source programování na FEL. Ale znamená to někoho, kdo se opravdu v C vyjadřuje plynně. Sám na takové pěkné psaní bohužel čas v dohledné době mít nebudu.
Zvláštní. Dělám pro ARMy a ABI se několikrát změnilo.Situaci na ARMu nesleduji úplně detailně, ale pokud vím, tak se ABI nezměnilo, nýbrž se začalo používat jiné – deklarované jako nové a jinak pojmenované. Není to tedy tak, že by se člověku bez varování změnilo pod rukama.
Stejně tak ABI není definováno příliš konkrétně. Pro sdílené knihovny a různé moduly je definováno někdy pouze to, které registry se musí při volání zachovat, a jak se předává int a pointer. A tím ABI končí.Vážně by mně zajímalo, jestli jste někdy nějakou specifikaci linuxového ABI četl
V C na Linux by rozhodně neměla. Standardní ABI tyto věci definuje velmi konkrétně.No, to už se ale moc netýká jazyka jako takového. Každopádně, původní argument byl, že C má jednoznačné ABI, zatímco C++ ne. Už nějak nevím, o čem je diskuse
Každopádně, původní argument byl, že C má jednoznačné ABI, zatímco C++ ne.Pak je otázkou, kdo takový argument položil. Pokud máš pocit, že já, problém bude spíše v porozumnění, zkus si můj komentář přečíst pozorněji.
realloc()
), v objektových jazycích typu C++ je na to přehršel už hotových objektů a ve zbytku většinou ukazatele vůbec nejsou.
Mimo toho, procházení spojového seznamu sice vypadá hezky na papíře, ale na reálném stroji, kde existují cache a paměť je proti CPU velmi pomalá, může být v patologickém případě rozdíl v rychlosti mezi spojovým seznamem a polem řádově takový, jako je rozdíl mezi rychlostí cache a necachované paměti. A když se k tomu ještě přidá fragmentace hromady a swapování ...
V Céčku a spol. jsou mnohem rychlejší a pohodlnější dynamicky (re)alokovaná pole (viz fce realloc()), v objektových jazycích typu C++ je na to přehršel už hotových objektů a ve zbytku většinou ukazatele vůbec nejsou.Pravdou je, že technicky jsou seznamy hodnot realizované spojově a polem dost odlišné, ač to někteří mí přátelé užívající GLib zcela ignorují. Já osobně na drtivou většinu věcí používám pole a právě ten realloc, protože nejjednodušší přístupové API, co můžu uživateli knihovny dát, je dvojice funkcí, z nichž jedna vrátí počet prvků a druhá vrátí nějakou reprezentaci prvku na základě indexu. Implementace bez dalších knihoven je triviální, kdy stačí zvětšit velikost paměti o jeden prvek s možnou optimalizaci na rezervování místa v případě výkonnostních problémů nebo když už předem vím, že se jedná o načítání velkého množství malých jednotek. Běžně nenarážím na situaci, kdy bych dal přednost spojovému seznamu, ale na druhou stranu běžně neudržuju velké množství dat, kde hraje roli pořadí a na kterých by probíhalo velké množství lokálních úprav. Třeba v textovém editoru bych realloc celého souboru při vložení nového řádku viděl nerad. Na druhou stranu si umím představit i jiná řešení.
use std::iter::Iterator;
enum List<T>
{
Node(T, ~List<T>),
Nil
}
impl<'lf, T: Clone> List<T>
{
fn new(vector: &[T]) -> List<T>
{
let mut list: List<T> = Nil;
for el in vector.rev_iter()
{
list = Node((*el).clone(), ~list);
}
list
}
fn add(&mut self, item: T)
{
match *self
{
Node(_, ref mut next) => next.add(item),
Nil => *self = Node(item, ~Nil)
}
}
fn iter(&'lf self) -> ListIterator<'lf, T>
{
ListIterator{ current: self }
}
fn each(&self, function: |e: &T|)
{
for e in self.iter()
{
function(&e);
}
}
}
struct ListIterator<'lf, T>
{
priv current: &'lf List<T>
}
impl<'lf, T: Clone> Iterator<T> for ListIterator<'lf, T>
{
fn next(&mut self) -> Option<T>
{
match *self.current
{
Node(ref value, ~ref next) => { (*self).current = next; Some((*value).clone()) }
Nil => None
}
}
}
fn main()
{
let mut list: List<int> = List::new([1, 2, 3]);
list.add(4);
list.add(5);
list.each(|e| print!("{} ", *e));
println!("");
}
Bylo to náročnější než jsem čekal a ty borrowed reference a lifetimes mi pořád ještě nejsou úplně jasný. Ale jinak zajímavej pokus...
Tiskni
Sdílej: