F# a Recordy rubrika: Programování: .Net
Na uvod vysvetlim co su recordy. Kedze vacsina .NET programatorov pouziva jazyk C# s recordami bezne neprichadzaju do kontaktu. V F# mame okrem tried (ktore funguju rovnako ako triedy v ostatnych .NET jazykoch) aj Recordy.
Record je nieco medzi triedou a strukturou tym co poznaju JS asi najviac pripomina plain object. Je to vlastne taka prepravka na data alebo anemicky objekt. Teda jazyk nam vyslovene nebrani v tom aby record obsahoval aj metody, alebo dokonca vnutorny stav ako u beznycxh tried ale nepouziva sa to. Record ma jednoducho syntax prisposobneu na funkcionalne programovanie. Priklady
// deklaracia typu recordu: type Person = { FirstName : string LastName : string Age : byte } // inicializacia recordu let pata = { FirstName = "Pata" LastName = "Buckova" Age = 22 Company = "PlutonKrea" Profession = "Consultant" }
Recordy sa pri funkcionalnom programovani oplati pouzivat preto ze su immutable, podporuju jednoduche klonovanie, alebo update len niektorych hodnot. Zoberiem rekord "pata" a chcem vytvorit novy rekord "karin" s vekom 20 rokov a inym menom:
let karin = { pata with Age = 20 FirstName = "Karin" LastName = "Ivancikova" }
hodnoty Company a Profession ostanu rovnake ako v recorde "pata" pretoze sa povodny record okopiroval.
v novej verzii F# mame okrem toho aj anonymne recordy, ktore nepotrebuju definovat typ recordu ale tym sa teraz nechcem venovat (az na iny zapis funguju uplne rovnako) tak len jeden priklad:
let car = {| Brand = "Tesla" Model = "S" Colour = "Red" |}
v com su recordy ine ako trieda:
- su immutable (da sa samozrejme spravit aj mutable record ale treba k tomu jazyk vyslovene donutit)
- jednoduchsia syntax zapisu
- jednoduche klonovanie - klonovanie je pri funkcionalnom programovani dost uzicotna vec
- membery su public (teoreticky si viem pridat aj private membery ale ide to proti ich filozofii)
- moze sice obsahovat aj metody ci properties (getter / setter), ale bezne sa tam metody nepridavaju (nato su urcene plnokrvne triedy)
- narozdiel od struktury je Record referencny typ vytvarany na heape - atributmi sa da donutit aby bol hodnotovy v tom pripade to bude obycajna struktura.
Samozrejme pri immutable recordoch rozdiel medzi hodnotovym a referencnym typom na prvy pohlad nevidime. Ale ked si spravime mutable record tak hned je jasne ze ide o referencny typ - recordy nepodporuju dedicnost ani implementovanie interfacov.
- v C# sa recordy z jazyka F# tvaria ako bezna anemicka trieda.
A teraz problem:
Problemom je ta dedicnost a nemoznost implementovat interface. V .NET je vsetko postavene na interfacoch. Mam jednu kniznicu, ktora pracuje len s objektami implementujucimi jeden interface (neni dolezite aky). No rad by som na ten ucel pouzil recordy ale bez toho aby record imlemetoval dany interface sa to neda.
Neda sa nejakym atributom povedat .NETu ze trieda implementuje taky a taky interface? (pricom potrebne metody by som tam rucne popridaval?)
Pokud si pamatuju pak implementovat interface jde:
type IMyInterface = abstract GetValue: unit -> string type MyRecord = { MyField1: int MyField2: string } interface IMyInterface with member x.GetValue() = x.MyField2
Pro zobrazení všech 5 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře