Dezvoltare Cum se programează cu Swift. Să facem prima aplicație. O privire de ansamblu rapidă asupra limbii Swift. Cel mai secret proiect al Apple

O selecție de cursuri, site-uri web și buletine informative care vă vor ajuta să stăpâniți Swift într-o lună.

Am început să învăț Swift acum exact 30 de zile. Acum trei zile, aplicația mea a fost aprobată de Apple pentru testare beta. Este clar că beta este încă departe de a fi ideală, dar pentru mine a fost o mare realizare.

Nu am o diplomă în informatică sau experiență ca dezvoltator, dar în ultimii 5 ani am fost manager de produs într-o echipă de dezvoltare software care scrie aplicații Ruby on Rails pentru distracție. Am vrut să fiu mai aproape de lucrurile cu care lucrez, așa că am început să codific.

De ce am ales iOS și Swift?

Popularitatea în continuă creștere a aplicațiilor mobile

Am vrut să lucrez la ceea ce au nevoie oamenii și mi-a plăcut întotdeauna intimitatea pe care utilizatorii o au cu smartphone-urile. Dispozitivele noastre știu totul despre noi: când ne trezim și când ne culcăm, unde suntem și cum am ajuns acolo, programul nostru, atitudinea noastră față de prieteni și familie și multe altele despre care nici măcar utilizatorul însuși nu știe. Imi place. De asemenea, sunt un fan Apple de mult timp, așa că a fost firesc să încep cu iOS. Am petrecut ceva timp învățând despre Objective-C, nu mi-a plăcut și am decis să învăț Swift.

Limitările sunt benefice

Dezvoltarea aplicațiilor în cadrul stabilit de Apple este destul de accesibilă unui începător și nu limitează foarte mult posibilitățile. Dar nu am fost tentat să fiu distras de nimic altceva și m-a forțat să mă gândesc mai mult la UX.

Swift este o limbă în creștere rapidă.

Îmi place să fiu la origini, să cresc și să mă dezvolt împreună, din acest motiv prefer să lucrez în startup-uri. Așa că aici, Swift nu este încă atât de popular și îmi place să fiu cu o comunitate de oameni care au aceleași idei.

Resurse pentru începători

Când am început să studiez, mi-a venit o idee pentru o aplicație simplă. Acest lucru m-a ajutat să rămân motivat și să învăț elementele de bază pas cu pas.

Am petrecut mult timp căutând resurse bune, instrucțiuni și cursuri online. Am găsit o mulțime de lucruri interesante pentru începători, pentru cei care nu au văzut o linie de cod și am decis că va fi prea lent. În același timp, articolele tehnice și materialele de referință (inclusiv de la Apple) s-au dovedit a fi destinate dezvoltatorilor mai experimentați.

La final am găsit o cale de mijloc, mai jos sunt materialele care mi s-au părut cele mai utile:

1. Curs Stanford de Paul Hegarty „Dezvoltarea aplicațiilor Swift pentru iOS 8”.

Disponibil gratuit pe iTunes U (inclusiv Windows). Mi-a luat aproximativ o săptămână să urmăresc primele cinci prelegeri și să-mi fac temele. În timpul procesului de învățare, am întâmpinat dificultăți și a trebuit să trec la alte resurse. Cu toate acestea, plănuiesc să-mi continui studiile în curând. Și acest site vă va ajuta să vă dați seama ce nu înțelegeți.

2. Curs de la Școala Superioară de Economie „Dezvoltarea aplicațiilor iOS în Swift”.

Cursul se bazează pe cartea „Swift: Limbajul de programare”. Pentru instruire, veți avea nevoie de experiență în dezvoltare în orice limbaj de programare (cel puțin la nivelul de bază). În general, cursul oferă o bună pregătire pentru a începe să lucrați la aplicațiile dvs.

3.RayWenderlich.com

Nu, acesta nu este site-ul personal al cuiva. Acesta este cel mai bun pe care l-am găsit vreodată. Daca abia esti la inceput, te sfatuiesc sa te abonezi la newsletter si sa folosesti tutorialul postat pe site. Datorită lui, am aflat pentru prima dată despre lucruri ciudate și am aflat cum să le fac. După ce ați citit, începeți să căutați idei. Dacă nu funcționează, caută-l pe google.

Planul meu de timp

Săptămâna 1. M-am cufundat în prelegerile și temele cursului Stanford, în timp ce citeam simultan cartea pe care s-a bazat cursul HSE și studiam resursele RayWenderlich.com. La sfârșitul primei săptămâni, am decis că sunt gata să încep să lucrez la aplicație.

Săptămânile 2 și 3. În acest timp am plecat într-o scurtă călătorie, în timpul călătoriei nu am avut acces la internet și am descărcat mai mult de 40 de file în avans. Acest lucru mi-a oferit oportunitatea de a lucra la aplicație fără distrageri. În fiecare zi mă gândeam cum să o fac mai bună.

Săptămâna 4: Am continuat să curăț codul inutil, să desenez o siglă în Sketch și am pregătit aplicația pentru a fi trimisă la Apple pentru revizuire. Am primit un raspuns in mai putin de 24 de ore.

Am petrecut 15 ore lucrând în Xcode, 3 ore în emulatorul iOS, mai mult de 4 ore citind tutoriale și aproximativ o oră căutând răspunsuri pe Stack Overflow. Am petrecut mult timp studiind materiale folosind smartphone-ul meu (nu am numărat acest timp).

miden16 10 iunie 2014 la 13:06

Limbajul de programare rapid. Versiunea rusă

  • Dezvoltare pentru iOS,
  • Rapid

Bună, Habr! Pe 2 iunie, cu toții am putut vedea cu ochii noștri cum Apple a început să creeze o revoluție în tabăra dezvoltatorilor Objective-C, prezentând lumii noul său limbaj de programare - Swift. Totodată, ea a pus la dispoziția publicului o mică documentație despre limbă, pe care am decis să o traducem dacă va fi cerere. Vă prezentăm atenției o traducere a primului capitol. Dacă subiectul este interesant, vom continua să publicăm traducerea în fiecare săptămână.

Ghid de limbă
Bazele
Operatori de bază
Șiruri și caractere
Tipuri de colecție
Controlul fluxului
Funcții
Închideri
Enumerări
Clase și Structuri
Proprietăți
Metode
Indicele
Moştenire
Inițializare
Deinițializarea
Numărarea automată a referințelor
Înlănțuire opțională
Tip Casting
Tipuri imbricate
Extensii
Protocoale
generice
Operatori avansati

Limbă de referință
Despre limbajul de referință
Structura lexicală
Tipuri
Expresii
Declarații
Declarații
Atribute
Modele
Parametri și argumente generice
Rezumatul Gramaticei
Mărci comerciale

Bun venit la Swift

Despre limba Swift
Swift este un nou limbaj de programare pentru dezvoltarea de aplicații iOS și OS X care combină cele mai bune din C și Objective-C, dar fără restricțiile impuse de dragul compatibilității cu C. Swift utilizează modele de programare sigure și adaugă caracteristici moderne care fac crearea unui aplicare într-un proces mai simplu, mai flexibil și mai distractiv. Creat de la zero de noi, Swift este o oportunitate de a reimagina modul în care sunt dezvoltate aplicațiile.

Swift este în dezvoltare de câțiva ani. Baza noului limbaj de programare a fost compilatorul, depanatorul și cadrele existente. Am simplificat gestionarea memoriei cu contorizarea automată a referințelor (ARC). Cadrele noastre au suferit, de asemenea, o modernizare majoră. Objective-C a început să susțină blocuri, literale și module - toate acestea au creat condiții favorabile pentru introducerea tehnologiilor moderne. Această lucrare pregătitoare a servit drept fundație pentru un nou limbaj de programare care va fi folosit pentru a dezvolta viitoare produse software pentru Apple.

Dezvoltatorii Objective-C vor găsi Swift familiar. Combină lizibilitatea parametrilor numiți cu puterea modelului de obiect dinamic al Objective-C. Deschide cadrele existente Cocoa și este compatibil cu codul scris în Objective-C. Construit pe această bază comună, limbajul oferă multe caracteristici noi și unifică aspectele procedurale și orientate pe obiecte ale limbajului de programare.

Nici Swift nu va speria programatorii începători. Este primul limbaj de programare puternic care este la fel de intuitiv și distractiv ca un limbaj de scripting. Acceptă așa-numitele locuri de joacă, care permit programatorilor să experimenteze cu codul, văzând rezultatul în timp real, fără a fi nevoiți să compileze și să ruleze aplicația.

Swift încorporează cele mai bune limbi moderne și este dezvoltat ținând cont de experiența vastă a Apple. Compilatorul nostru este sinonim cu performanța, iar limbajul nostru este optimizat pentru dezvoltare fără compromisuri. Este conceput astfel încât să puteți dezvolta cu ușurință prima dvs. aplicație „bună, lume!” și chiar un întreg sistem de operare. Toate acestea fac din Swift un instrument important pentru dezvoltatori și pentru Apple însuși.

Swift este o nouă modalitate fantastică de a crea aplicații pentru iOS și OS X și vom continua să o dezvoltăm adăugând noi funcționalități și introducând noi funcții. Scopul nostru este ambițios. Și abia așteptăm să vedem ce poți crea cu el.

Introducere în Swift
Conform unei tradiții de lungă durată, primul program într-o limbă nouă ar trebui să afișeze pe ecran cuvintele „Bună ziua, lume”. Cu Swift se procedează astfel:

Println(„Bună ziua, lume”)
Dacă ați dezvoltat vreodată în C sau Objective-C, această sintaxă ar trebui să vă sune ciudat de familiară - în Swift, această linie de cod este un program complet. Nu mai trebuie să importați biblioteci separate pentru a oferi funcționalități de bază, cum ar fi I/O console sau manipularea șirurilor. Codul scris în domeniul global este punctul de intrare în program, astfel încât funcția principală nu mai este necesară. De asemenea, rețineți că nu există punct și virgulă la sfârșitul fiecărei linii.

Această introducere oferă suficiente informații pentru a începe să codificați în Swift. Nu vă faceți griji dacă nu înțelegeți ceva - vă vom explica totul în detaliu în capitolele următoare.

Comentariu
Pentru o mai bună înțelegere a materialului, vă recomandăm să folosiți modul loc de joacă în Xcode. Playground vă permite să vedeți rezultatele imediat pe măsură ce editați codul, fără a fi nevoie să compilați și să rulați aplicația.
Tipuri de date simple
Utilizați let pentru a crea o constantă și var pentru a crea o variabilă. Tipul constantei nu trebuie să fie specificat, îi puteți atribui o valoare o singură dată.

Var myVariable = 42 myVariable = 50 las myConstant = 42
Tipurile unei constante și ale unei variabile trebuie să se potrivească cu tipurile valorilor corespunzătoare care le sunt atribuite. Cu toate acestea, acest lucru nu înseamnă că trebuie să specificați direct tipul lor. Compilatorul va determina automat tipul de constantă și variabilă atunci când le atribuie o valoare. Deci, în exemplul de mai sus, compilatorul va determina că myVariable este un tip întreg.

Dacă inițializatorul lipsește sau nu oferă suficiente informații, puteți specifica singur tipul după variabilă, separând numele și tipul cu două puncte:

Fie implicitInteger = 70 let inplicitDouble = 70.0 let inplicitDouble: Double = 70

Să experimentăm
Creați o constantă cu tipul Float și inițializați-o cu numărul 4.

Valorile nu sunt niciodată convertite implicit într-un alt tip. Dacă trebuie să convertiți o valoare într-un alt tip, faceți-o în mod explicit:
let label = "Lățimea este " let width = 94 let widthLabel = label + String(width)
Să experimentăm
Încercați să eliminați conversia explicită în String din ultima linie. Ce eroare vei primi?

O modalitate mai ușoară de a include valori în șiruri este de a include expresia în paranteze și de a le preceda cu o bară oblică inversă (\). Exemplu:

Let apples = 3 let oranges = 5 let appleSummary = "Am \(mere) mere." let fruitSummary = "Am \(mere + portocale) bucăți de fructe."

Să experimentăm
Încercați să utilizați construcția \() și să imprimați un șir care include rezultatul sumei a două variabile întregi și numele cuiva.

Când lucrați cu matrice și matrice asociative (dicționare), se folosesc paranteze drepte ():

Var shoppingList = ["somn", "apă", "lalele", "vopsea albastră"] shoppingList = "sticlă de apă" var ocupations = [ "Malcolm": "Căpitan", "Kaylee": "Mecanic", ] ocupații ["Jayne"] = "Relații publice"
Pentru a crea o matrice sau un dicționar gol, utilizați următoarea sintaxă:

Let emptyArray = String() let emptyDictionary = Dicţionar ()
Pentru a crea matrice și dicționare goale, utilizați și respectiv [:] - de exemplu, când atribuiți o nouă valoare unei variabile sau treceți un argument unei funcții.

ShoppingList = // A fost la cumpărături și a cumpărat totul.

Condiții și cicluri
Instrucțiunile If și switch sunt folosite pentru a crea condiții, iar instrucțiunile for-in, for, while și do-while sunt folosite pentru a crea bucle. În acest caz, nu este necesară evidențierea condițiilor și inițializarea expresiilor cu paranteze, în timp ce sunt necesare acolade.

Fiți individualScores = var teamScore = 0 pentru scor în individualScores ( dacă scor > 50 ( teamScore += 3 ) else ( teamScore += 1 ) ) teamScore
Condiția din interiorul instrucțiunii if trebuie să fie booleană, ceea ce înseamnă în mod specific că instrucțiunea if score (...) este o eroare deoarece nu există o comparație explicită (de exemplu, cu zero).

Declarația if poate fi utilizată împreună cu let și var pentru a lucra cu constante și variabile care pot avea o valoare zero. Astfel de constante și variabile sunt numite opționale (adică pot lua orice valoare sau pot fi egale cu zero). Pentru a crea o variabilă sau o constantă opțională, adăugați un semn de întrebare (?) după tip.

Var optionalString: String? = „Salut” optionalString == nil var optionalName: String? = "John Appleseed" var salut = "Bună ziua!" if let name = optionalName ( salut = "Bună ziua, \(nume)" )

Să experimentăm
Schimbați opționalName în nil . Ce vezi pe ecran? Adăugați un bloc else pentru a gestiona cazul în care optionalName este nil .

Dacă valoarea opțională este nil , condiția va fi falsă, iar codul din acolade după if nu va fi executat. În caz contrar, variabilei de salut i se va atribui o nouă valoare.

Comutatorul cu opțiuni multiple acceptă mulți alți operatori de comparație în sine și nu se limitează la comparații simple:

Let vegetable = "ardei roșu" comutați legume ( case "telina": let vegetableComment = "Adăugați niște stafide și faceți furnici pe un buștean." case "castraveți", "cresturel": let vegetableComment = "Asta ar fi un sandwich bun cu ceai ." case let x where x.hasSuffix("piper"): let vegetableComment = "Este un \(x) picant?" implicit: let vegetableComment = "Totul are gust bun în supă." )

Să experimentăm
Încercați să eliminați condiția implicită. Ce eroare vei primi?

După executarea blocului de cod corespunzător, programul părăsește instrucțiunea switch fără a verifica condițiile ulterioare. În acest fel, nu trebuie să adăugați manual instrucțiuni break la sfârșitul fiecărui bloc de caz.

Pentru a itera elementele unui tablou asociativ, utilizați instrucțiunea for-in împreună cu specificarea unei perechi de nume pentru fiecare pereche cheie-valoare.

Fie interestingNumbers = [ "Prime": , "Fibonacci": , "Square": , ] var cel mai mare = 0 pentru (tip, numere) în InteresingNumbers ( pentru numărul în numere ( dacă număr > cel mai mare ( cel mai mare = număr ) ) ) cel mai mare

Să experimentăm
Adăugați o altă variabilă care vă va permite să aflați care dintre cele trei tipuri este numărul maxim găsit.

Instrucțiunea while loop vă permite să executați un bloc de cod în cadrul acestuia până când condiția devine falsă. Condiția poate fi specificată și după bloc, care în acest caz va fi executată cel puțin o dată.

Var n = 2 în timp ce n< 100 { n = n * 2 } n var m = 2 do { m = m * 2 } while m < 100 m
Instrucțiunea for poate fi folosită pentru a itera pe o secvență de numere folosind două puncte (..) sau folosind un inițializator, o condiție și un increment. Uite, aceste două bucle fac același lucru:

Var firstForLoop = 0 pentru i în 0..3 ( firstForLoop += i ) firstForLoop var secondForLoop = 0 pentru var i = 0; i< 3; ++i { secondForLoop += 1 } secondForLoop
Când creați o buclă, utilizați două puncte (..) dacă nu doriți să includeți valoarea mai mare în interval și trei puncte (...) pentru a include atât valorile mai mici, cât și cele mai mari.

Funcții și închideri.
Pentru a declara funcții, utilizați cuvântul cheie func. O funcție este apelată prin specificarea numelui și a unei liste de argumente între paranteze. Tipul returnat trebuie separat de lista formală de argumente folosind -> .

Func greet(nume: String, day: String) -> String ( returnează "Bună ziua \(nume), astăzi este \(ziua)." ) greet("Bob", "Marți")

Să experimentăm
Eliminați parametrul zi. În schimb, adăugați o variabilă care indică numele felului de mâncare servit la prânz.

Dacă o funcție returnează mai multe valori, ar trebui să utilizați un tuplu:

Func. getGasPrices() -> (dublu, dublu, dublu) ( return (3,59, 3,69, 3,79) ) getGasPrices()
Funcțiile pot avea, de asemenea, un număr nedefinit de argumente:

Func sumOf(numbers: Int...) -> Int ( var sum = 0 pentru numărul în numere ( sum += number ) return sum ) sumOf() sumOf(42, 597, 12)

Să experimentăm
Scrieți o funcție care vă permite să găsiți media aritmetică a unui număr arbitrar al argumentelor sale.

Funcțiile pot fi imbricate unele în altele. O funcție imbricată poate accesa variabilele declarate în funcția exterioară. Utilizați funcții imbricate pentru a aranja codul unei funcții complexe sau mari.

Func returnFifteen() -> Int ( var y = 10 func add() ( y += 5 ) add() return y ) returnFifteen()
Funcțiile sunt obiecte din prima clasă (tip de primă clasă), cu alte cuvinte, o funcție poate returna o altă funcție ca rezultat.

Func makeIncrementer() -> (Int -> Int) ( func addOne(number: Int) -> Int ( return 1 + number ) return addOne ) var increment = makeIncrementer() increment(7)
O funcție poate lua, de asemenea, o altă funcție ca unul dintre argumentele sale.

Func hasAnyMatches(listă: Int, condiție: Int -> Bool) -> Bool (pentru elementul din listă (dacă condiția (articolul) ( returnează adevărat ) ) returnează fals ) func lessThanTen (număr: Int) -> Bool ( returnează numărul< 10 } var numbers = hasAnyMatches(numbers, lessThanTen)
Funcțiile sunt un caz special de închidere. Puteți crea o închidere fără a specifica un nume și înconjurând corpul închiderii cu acolade (()). Pentru a separa argumentele și tipul de returnare din corpul închiderii, utilizați operatorul in.

Numbers.map(( (număr: Int) -> Int în let rezultat = 3 * număr returnează rezultat ))

Să experimentăm
Rescrieți închiderea astfel încât să returneze zero pentru toate numerele suplimentare.

Există mai multe tehnici pentru a face închiderile mai concise. Dacă tipul de închidere este cunoscut a priori (de exemplu, este un callback delegat), puteți omite specificarea tipului parametrilor săi și/sau tipul valorii returnate. Închiderile constând dintr-o singură expresie returnează implicit rezultatul acelei expresii.

Numbers.map(( număr în 3 * număr ))
Într-o închidere, în loc să specificați un nume de variabilă, puteți utiliza numărul său ordinal - acest lucru este util în special atunci când scrieți scurtcircuite. Închiderea, care este ultimul argument al funcției, îi poate fi transmisă imediat după paranteze cu o listă a parametrilor rămași.

Sortare() ($0 > $1)

Obiecte și clase
Pentru a crea o clasă, utilizați clasa de cuvinte rezervată. Membrii clasei sunt declarați în același mod ca constantele și variabilele obișnuite. Mai mult, metodele de clasă sunt declarate ca funcții obișnuite.

Forma clasei ( var numberOfSides = 0 func simpleDescription() ->

Să experimentăm
Adăugați o constantă de membru de clasă și o metodă de clasă care o ia drept argument.

Pentru a crea o instanță (obiect) a unei clase, trebuie doar să adăugați paranteze după numele clasei. Metodele și membrii clasei sunt accesați printr-un punct.

Var shape = Shape() shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()
În acest exemplu, am omis un detaliu important - constructorul clasei, metoda init.

Clasa NamedShape ( var numberOfSides: Int = 0 var name: String init(name: String) ( self.name = name ) func simpleDescription() -> String ( returnează „O formă cu \(numberOfSides) laturi.” ) )
Observați cum membrul clasei nume este separat de argumentul constructorului de nume de către sine. Argumentele sunt transmise constructorului în mod normal, ca la orice altă metodă de clasă. Rețineți că fiecare membru al clasei trebuie să fie inițializat, fie atunci când este declarat (cum ar fi numberOfSides), fie în constructor (cum ar fi numele).

Destructorul de clasă este metoda deinit, care poate fi suprascrisă dacă este necesar.

Pentru a moșteni o clasă dintr-o clasă existentă, după ce ați specificat numele clasei copil, adăugați două puncte și indicați numele clasei părinte. În Swift nu există restricții privind moștenirea obligatorie a oricărei clase standard.

Metodele suprascrise de o clasă copil trebuie să fie marcate cu cuvântul cheie override - suprascrierea metodelor fără override va duce la o eroare. Compilatorul detectează, de asemenea, metodele care sunt marcate ca suprascrie, dar nu înlocuiesc nicio metodă din clasa lor părinte.
class Square: NamedShape ( var sideLength: Double init(sideLength: Double, nume: String) ( self.sideLength = sideLength super.init(name: name) numberOfSides = 4 ) func area() -> Double ( return sideLength * sideLength ) override func simpleDescription() -> String ( return "Un pătrat cu laturile lungimii \(sideLength)." ) ) let test = Square(sideLength: 5.2, nume: "pătratul meu de testare") test.area() test.simpleDescription ()

Să experimentăm
Creați o clasă Circle și moșteniți din clasa NamedShape. Constructorul clasei Circle are două argumente: rază și nume. Ignorați zona și descrieți metodele acestei clase.

Membrii clasei pot avea, de asemenea, propriul lor getter și setter.

Clasa Triunghi Echilateral: NamedShape ( var sideLength: Double = 0.0 init(sideLength: Double, nume: String) ( self.sideLength = sideLength super.init(name: name) numberOfSides = 3 ) var perimetru: Double ( get ( return 3.0 * sideLength ) ) set ( sideLength = newValue / 3.0 ) ) override func simpleDescription() -> String ( return "Un triunghi echilateral cu laturile de lungime \(sideLength)." ) ) var triangle = EquilateralTriangle(sideLength: 3.1, nume: "un triunghi ") triunghi.perimetru triunghi.perimetru = 9,9 triunghi.laturaLungime
În setatorul variabilei perimetru, noua valoare atribuită se numește implicit newValue . Puteți schimba numele acestei variabile punând-o între paranteze imediat după set .

Observați structura constructorului clasei EquilateralTriangle. Această metodă include trei pași succesivi:

  1. inițializarea membrilor unei clase de copii;
  2. apelarea constructorului clasei părinte;
  3. modificarea valorilor membrilor clasei părinte.
Dacă trebuie să executați un anumit cod înainte sau după alocarea unei noi valori unei variabile, puteți suprascrie metodele willSet și didSet pentru a se potrivi nevoilor dumneavoastră. De exemplu, clasa de mai jos garantează că lungimea laturii unui triunghi va fi întotdeauna egală cu lungimea laturii unui pătrat.

Clasa TriunghiAndPătrat ( var triunghi: EquilateralTriangle ( willSet ( square.sideLength = newValue.sideLength ) ) var square: Square ( willSet ( triangle.sideLength = newValue.sideLength ) ) init(size: Double, nume: String) ( square = Square( sideLength: size, name: name) triangle = EquilateralTriangle(sideLength: size, name: name) ) var triangleAndSquare = TriangleAndSquare(size: 10, name: "other test shape") triangleAndSquare.square.sideLength triangleAndSquare.triangle.sideLength triangle.AndSquare pătrat = Square(sideLength: 50, nume: „pătrat mai mare”) triangleAndSquare.triangle.sideLength
Metodele de clasă au o diferență importantă față de funcții. Numele argumentelor unei funcții sunt folosite numai în cadrul acelei funcție, în timp ce într-o metodă de clasă, parametrii sunt utilizați și la apelarea acelei metode (cu excepția primului parametru). În mod implicit, o metodă de clasă are aceleași nume de parametri atât atunci când este apelată, cât și în ea însăși. Cu toate acestea, puteți specifica un nume diferit (în exemplul de mai jos - ori), care va fi folosit numai în cadrul acestei metode. În acest caz, pentru a apela această metodă, trebuie să utilizați prenumele (numberOfTimes).

Class Counter ( var count: Int = 0 func incrementBy(amount: Int, numberOfTimes ori: Int) (count += amount * times ) ) var counter = Counter() counter.incrementBy(2, numberOfTimes: 7)
Când lucrați cu valori opționale, adăugați un semn de întrebare (?) înaintea metodelor, a membrilor clasei etc. Dacă valoarea de dinaintea semnului de întrebare este zero, totul după (?) este ignorat și întreaga expresie este zero. În caz contrar, expresia este evaluată ca de obicei. În ambele cazuri, întreaga expresie va avea ca rezultat o valoare opțională.

Lăsați opționalSquare: Square? = Square(sideLength: 2,5, nume: "opțional pătrat") let sideLength = optionalSquare?.sideLength

Enumerări și structuri
Cuvântul cheie enum este folosit pentru a crea enumerări. Rețineți că enumerațiile pot conține și metode.

Enum Rank: Int (case As = 1 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King func simpleDescription() -> String ( switch self (case .Ace: return " ace" case .Jack: returnează "jack" case .Queen: return "queen" case .King: return "king" implicit: return String(self.toRaw()) ) ) ) let ace = Rank.Ace let aceRawValue = as .toRaw()

Să experimentăm
Scrieți o funcție care compară 2 enumerari de rang pe baza valorilor lor.

În exemplul de mai sus, elementele enumerate sunt inițial de tip întreg și trebuie doar să specificați valoarea primului element - valorile elementelor rămase vor fi determinate în funcție de ordinea în care apar. De asemenea, puteți alege șir sau tipuri reale ca valoare brută a valorilor elementului.

Pentru a converti tipul de valoare original într-un tip de enumerare, utilizați funcțiile toRaw și fromRaw.

Dacă lăsați convertedRank = Rank.fromRaw(3) ( lăsați threeDescription = convertedRank.simpleDescription() )
Rețineți că valorile elementelor de enumerare sunt reale și nu doar o altă reprezentare a valorilor lor originale. În general, nu trebuie să specificați valorile lor originale.

Enum Suit ( case Spades, Hearts, Diamonds, Clubs func simpleDescription() -> String ( switch self ( case .Spades: return "spades" case .Hearts: return "hearts" case .Diamonds: return "diamonds" case .Clubs: returnează „cluburi” ) ) ) let hearts = Costum.Hearts let heartsDescription = hearts.simpleDescription()

Să experimentăm
Adăugați o metodă Color care returnează șirul „negru” pentru Spades și Trece și „roșu” pentru Hearts and Diamonds.

Observați cum este accesat membrul Hearts din enumerarea Suit. Când atribuim o valoare constantei inimi, folosim numele complet Suit.Hearts deoarece nu specificăm în mod explicit tipul constantei. Iar în switch folosim forma scurtă .Hearts deoarece tipul valorii de sine este cunoscut a priori. Puteți utiliza formularul scurt atâta timp cât tipul variabilei este specificat în mod explicit.

Cuvântul cheie struct este folosit pentru a crea structuri. Structurile au multe asemănări cu clasele, inclusiv metode și constructori. Una dintre cele mai semnificative diferențe dintre structuri și clase este că instanțele de structuri, spre deosebire de instanțele de clase, sunt transmise funcțiilor prin valoare (adică este creată mai întâi o copie locală a acestora), în timp ce instanțele de clase sunt transmise prin referință.

Struct Card ( var rank: Rank var suit: Suit func simpleDescription() -> String ( return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" ) ) let threeOfSpades = Card(rank: . Trei, costum: .Spades) let threeOfSpadesDescription = threeOfSpades.simpleDescription()

Să experimentăm
Adăugați o metodă la structura Cărților care creează un pachet complet de cărți.

O instanță de membru de enumerare poate avea propriile valori și pot fi diferite. Atribuiți aceste valori atunci când instanțiați enumerarea (constanta de succes din exemplu). Valorile legate și inițiale sunt lucruri diferite: valoarea inițială a unui membru al enumerației este întotdeauna constantă în toate instanțele enumerației și este specificată atunci când este declarată.

Să luăm în considerare un exemplu de primire a orelor de răsărit și apus de la un server. Serverul răspunde fie cu informații relevante, fie cu un mesaj de eroare.

Enum ServerResponse ( case Result(String, String) case Error(String) ) let success = ServerResponse.Result("6:00 am", "8:09 pm") let failure = ServerResponse.Error("Out of cheese." ) switch success ( case let .Result(sunrise, sunset): let serverResponse = "Răsăritul este la \(răsăritul) și apusul este la \(apusul)." case let .Eroare (eroare): let serverResponse = "Eșec.. .\(eroare)" )

Să experimentăm
Adăugați o a treia opțiune la o declarație switch cu alegere multiplă

Observați cum orele răsăritului și apusului sunt extrase din obiectul ServerResponse.
Protocoale și extensii.
Pentru a declara un protocol, utilizați cuvântul cheie protocol.

Protocol ExempluProtocol ( var simpleDescription: String ( get ) mutating func adjust() )
Protocoalele pot fi susținute de clase, enumerări și structuri.

Clasa SimpleClass: ExampleProtocol ( var simpleDescription: String = "O clasă foarte simplă." var anotherProperty: Int = 69105 func adjust() ( simpleDescription += " Acum 100% ajustat." ) ) var a = SimpleClass() a.adjust( ) let aDescription = a.simpleDescription struct SimpleStructure: ExampleProtocol ( var simpleDescription: String = "O structură simplă" mutating func adjust() ( simpleDescription += " (ajustat)" ) ) var b = SimpleStructure() b.adjust() let bDescription = b.simpleDescription

Să experimentăm
Creați o enumerare care va implementa acest protocol.

Observați cuvântul cheie mutant din definiția SimpleStructure, care spune compilatorului că metoda corespunzătoare modifică structura. În schimb, metodele clasei SimpleClass nu trebuie să fie marcate ca mutante, deoarece metodele clasei o pot schimba întotdeauna fără interferențe.

Pentru a adăuga noi metode sau membri de clasă la un tip existent, trebuie să utilizați extensii. De asemenea, puteți utiliza extensii pentru a implementa un protocol cu ​​un tip existent, chiar dacă este importat dintr-o bibliotecă sau cadru.

Extensie Int: ExampleProtocol ( var simpleDescription: String ( return "The number \(self)") ) mutating func adjust() (self += 42 ) ) 7.simpleDescription

Să experimentăm
Creați o extensie de tip Double cu o variabilă membru absoluteValue .

Puteți utiliza numele protocolului ca orice alt tip - de exemplu, pentru a crea o serie de obiecte de diferite tipuri, dar implementând un protocol comun. Rețineți că atunci când lucrați cu obiecte de acest tip, metodele declarate în afara protocolului nu vor fi disponibile.

Lăsați protocolValue: ExampleProtocol = a protocolValue.simpleDescription // protocolValue.anotherProperty // Anulați comentariul pentru a vedea eroarea
Chiar dacă variabila protocolValue este de tip SimpleClass în timpul rulării, compilatorul presupune că tipul ei este ExampleProtocol . Aceasta înseamnă că nu veți putea accesa accidental metode sau membri ai clasei care sunt implementate în afara ExampleProtocol.

Tipuri generice
Pentru a crea un tip generic, includeți numele între paranteze unghiulare (<>).

Func repetare (articol: ItemType, ori: Int) -> ItemType ( var rezultat = ItemType() pentru i în 0.. ori ( rezultat += item ) returnează rezultat ) repeat("knock", 4)
Creați funcții generice, clase, enumerări și structuri.

// Reimplementați tipul opțional al bibliotecii standard Swift OptionalValue (case Niciun caz Some(T) ) var posibilInteger: OptionalValue = .Nimic posibilIntreg = .Celeva(100)
Dacă doriți să specificați cerințe specifice pentru un tip generic, cum ar fi implementarea unui protocol sau solicitarea acestuia să moștenească de la o anumită clasă, utilizați where .

Func anyCommonElements (lhs: T, rhs: U) -> Bool ( pentru lhsItem în lhs ( pentru rhsItem în rhs ( dacă lhsItem == rhsItem ( returnează adevărat ) ) ) ) return false ) anyCommonElements(, )

Să experimentăm
Modificați funcția anyCommonElements pentru a returna o matrice de elemente comune.

În cazuri simple, puteți omite unde și puteți scrie protocolul sau numele clasei după două puncte. Expresie este echivalent cu expresia .

Swift este limbajul de programare robust și intuitiv al Apple pe care îl puteți folosi pentru a crea aplicații pentru iOS, Mac, Apple TV și Apple Watch. Oferă dezvoltatorilor o libertate creativă fără precedent. Cu acest limbaj open source simplu, ușor de utilizat, tot ce aveți nevoie este o idee interesantă pentru a crea ceva incredibil.

Dezvoltatorii folosesc deja
caracteristici uimitoare ale Swift.

Swift este un limbaj de programare rapid, eficient, în timp real, care poate fi inserat cu ușurință în codul Objective-C pre-construit. Acum dezvoltatorii pot nu numai să scrie cod mai fiabil și mai sigur, ci și să economisească timp și să creeze aplicații cu capabilități avansate.

Aplicație grozavă în Swift. Ușurința de utilizare și capacitatea de răspuns în timp real este motivul pentru care VSCO a ales Swift pentru a crea o nouă versiune a aplicației foto iOS.

Aplicații excelente,
dezvoltat în limbajul Swift.

Din ce în ce mai mulți dezvoltatori încorporează codul Swift în aplicațiile lor. Și unii chiar creează aplicații complet noi în Swift.

Duolingo Khan
Ghid pentru cerul senin al Academiei

Procreează Kickstarter Eventbrite Hipmunk

Productivitatea este mai mare. Aplicațiile sunt mai bune.

Aplicațiile Swift depășesc așteptările. De exemplu, algoritmul obișnuit de căutare rulează mult mai rapid în Swift.

Până la 2.6 ori mai rapid decât Obiectivul-C

Până la 8.4 ori mai rapid decât Python 2.7

10.000 de numere întregi au fost găsite în grafic folosind algoritmul de căutare depth-first*

A fost adăugat un limbaj rapid
în curriculum.

Nu doar dezvoltatorii apreciază potențialul limbajului Swift. Universitățile și alte instituții de învățământ predau Swift la cursuri de programare și publică cursuri gratuite pe iTunes U, ceea ce înseamnă că chiar și începătorii pot trece cu ușurință de la codificare de bază la programare de nivel profesional.

Universități care au inclus Swift în programa lor

  • Universitatea din California din Santa Cruz
  • Colegiul Foothill
  • Universitatea Regală de Tehnologie din Melbourne
  • Universitatea Tehnică din München
  • Colegiul Comunitar Lawson
  • Colegiul Comunitar din Manhattan
  • Colegiul Comunitar Mesa
  • Colegiul Comunitar din Houston
  • Colegiul Comunitar Central Piemont
  • Universitatea din Plymouth
  • Universitatea Politehnică de Stat din California
  • Universitatea Stanford
  • Colegiul Tehnic Northwest Kansas
  • Institutul Tehnologic din Monterrey
  • Universitatea Aberystwyth
  • Universitatea Full Sail
  • Scoala Ingesup
  • Universitatea Metodistă de Sud

Swift este peste tot.
Și acum este deschis tuturor.

Swift este disponibil gratuit pentru utilizare de către dezvoltatori, profesori și studenți sub licența de software open source Apache 2.0. Oferim sisteme binare OS X și Linux care vă permit să compilați cod pentru iOS, OS X, watchOS, tvOS și Linux. Și pentru a accelera dezvoltarea Swift într-un limbaj și mai puternic, am creat o nouă comunitate în care utilizatorii pot contribui direct la codul sursă Swift.

Faceți cunoștință cu Swift.

Registrul general

Descărcați tutorialul Limbajul de programare rapid din Apple Books Store gratuit. Aflați cum Swift face programarea mai convenabilă, mai flexibilă și mai distractivă.

Xcode

Xcode este o aplicație pentru Mac concepută pentru dezvoltarea altor aplicații pentru Mac și iOS. Xcode are toate instrumentele de care aveți nevoie pentru a crea aplicații uimitoare. Poate fi descărcat gratuit din Mac App Store.

Site-ul dezvoltatorului

Obțineți informații tehnice aprofundate și o prezentare completă a limbii Swift. Consultați blogul dezvoltatorului pentru cele mai recente știri. De asemenea, aveți acces gratuit la resurse excelente, cum ar fi tutoriale, videoclipuri și mostre de cod.

Nu cu mult timp în urmă, cunoscuta companie Apple a introdus un nou limbaj de programare numit Swift. Un nou limbaj pentru dezvoltarea de programe pe IOS și OS X, care a absorbit cele mai bune calități ale strămoșilor săi, și anume limbajele C și Objective-C, împingând în același timp principalele lor deficiențe.

După cum a spus Apple, limbajul a fost creat aproape de la zero și folosește modele de programare sigure, folosind funcții moderne, care ar trebui să facă procesul de creare a aplicațiilor mai rapid și mai ușor [desigur, dacă înțelegeți cum trebuie create aceste aplicații în general].

Apropo, voi spune că limbajul a apărut pe 2 iunie 2014, iar multe site-uri IT [cum ar fi HUB] au reușit deja să discute toate avantajele, dezavantajele și așa mai departe ale acestui limbaj. Întreaga evaluare a fost de acord că această limbă este foarte interesantă și demnă de învățat.

Acest articol este un fel de introducere în limbajul Swift, deoarece intenționez să scriu mai multe lecții despre el, așa că dacă ești interesat de el, îl vom studia cu tine.

Din păcate, sau poate din fericire, nu există surse normale, în limba rusă, din care să puteți învăța această limbă. Pentru că, după cum știe toată lumea, 90% din informații sunt lansate pe piața în limba engleză și, deși sunt traduse în rusă, își vor pierde deja relevanța, așa că singura modalitate de a ține pasul cu vremurile este să citești cărți în limba engleză.

Ceea ce intenționez să fac exact. Nu cu mult timp în urmă am terminat o carte uriașă despre limbajul C și m-am gândit să trec la Objective-C, dar mi-am dat seama că în curând își va pierde relevanța [dacă nu complet, atunci într-o anumită parte], așa că alegerea a căzut pe Swift.

Bun venit la Swift

După cum se dovedește, Swift a fost în lucru de ani de zile și este posibil să fi fost conceput sub Jobs. Apple a pus bazele limbajului în procesul de promovare a infrastructurii compilatorului, depanatorului și cadru. Sistemul de gestionare a memoriei a fost simplificat semnificativ folosind contorizarea automată a referințelor.

Datorită Objective-C, care a început să accepte blocuri, literale și module, a devenit posibilă crearea unei tehnologii moderne de limbaj. Datorită acestei fundații, Apple a reușit să creeze un nou limbaj care va deveni viitorul tuturor dezvoltării de software pentru Apple.

Acei oameni (dezvoltatori) deja familiarizați cu Objective-C vor găsi Swift destul de familiar, deoarece combină o bună citire a parametrilor cu puterea modelului de obiect dinamic al strămoșului său. Pentru mulți, va fi o mare bucurie că Swift este compatibil cu Objective-C și poate fi încorporat în codul său. Construit pe o bază comună, Swift oferă multe caracteristici și unifică aspectele procedurale și orientate pe obiecte ale limbajului.

Din fericire pentru noi, cei care vrem să învețe să programăm în Swift, limba este destul de prietenoasă și nu necesită un IQ de peste 200 pentru a o stăpâni. Acesta, după cum spun dezvoltatorii, este primul limbaj care are suficientă putere și, în același timp, este la fel de interesant și simplu ca un limbaj de scripting [sau așa cum este numit și limbaj de scripting].

Există suport pentru teren de joacă, care este foarte dificil de tradus adecvat, dar dacă este explicat în cuvinte simple, acesta este suport pentru o funcție care vă permite să vedeți aplicația (programul) pe care o creați fără a compila și rula proiectul.

A absorbit tot ce este mai bun din toate limbajele de programare și întreaga cultură și experiență a inginerilor Apple. Compilatorul XCode combină calitatea și performanța ridicată, iar limbajul este optimizat maxim pentru dezvoltator, fără niciun compromis.

Se așteaptă ca scrierea primului tău program (și anume „Hello, World”) să fie la fel de ușoară ca și scrierea unui întreg sistem de operare. Toate acestea fac din Swift viitorul dezvoltării pentru Apple și întreaga lume.

Swift este o modalitate fantastică de a scrie o aplicație pentru iOS și OS X. Scopul limbajului este ambițios și suntem încântați să vedem ce puteți crea cu el!

Limbajul de programare rapid - Apple

Atât, cred că este suficient pentru introducere. Am încercat să traduc în mod adecvat introducerea dintr-o carte în limba engleză despre această limbă, în același timp diluând-o cu fraze de la mine, sper că nu a ieșit rău. Dacă sunteți interesat de această limbă, atunci abonați-vă la actualizările blogului și începeți să învățați această limbă cu mine - mult succes tuturor.

Chris Lattner a petrecut un an și jumătate creând un nou limbaj de programare. În acest timp, nu a vorbit nimănui despre munca sa, nici măcar dintre prietenii apropiați. A început să lucreze în vara lui 2010, dedicând nopți și weekend-uri sarcinii, iar până la sfârșitul anului următor a dezvoltat bazele viitoarei limbi. Abia atunci Chris și-a dezvăluit secretul în cadrul companiei, ai cărei manageri de top au fost suficient de impresionați pentru a adăuga mai mulți ingineri cu experiență la proiect. Încă un an și jumătate mai târziu, proiectul lui Lattner a fost inclus în lista direcțiilor principale ale companiei, iar echipa de dezvoltare s-a extins semnificativ. Astăzi, o nouă limbă este pe cale de a schimba lumea calculatoarelor. Compania pentru care lucrează Chris Lattner se numește Apple, iar limbajul creat de el se numește Swift.

Pe 2 iunie 2014, la prezentarea WWDC, limba Swift. Compania a lansat o versiune de testare pentru dezvoltatori și programatori terți, poziționând limbajul ca o modalitate mai rapidă și mai eficientă de a crea programe pentru iPhone, iPad și Mac. Chiar și după ce Chris Lattner a început să lucreze la Swift, informațiile despre produs au șocat pe toată lumea, cu excepția unui număr limitat de angajați Apple. Chiar și oamenii care au fost implicați indirect în crearea limbii și l-au ajutat pe Chris au fost foarte surprinși să afle în această vară la ce lucrează exact.

Swift captează audiențe

De obicei, o nouă limbă este nevoie de câțiva ani după introducerea ei pentru a câștiga orice public. Această regulă se aplică chiar și companiilor mari precum Apple. Un bun exemplu este Google cu limba Go, introdus încă din 2009. Cele mai strălucite minți din lumea dezvoltării de software, Ken Thompson și Rob Pike, au lucrat la Go, dar până astăzi se fac eforturi considerabile pentru a se asigura că limbajul are adepți. Dar Swift este o altă rasă de fiare. Odată ce limbajul este lansat oficial în această toamnă, se așteaptă să câștige un public într-un ritm fără precedent, depășind rata de adoptare a limbajelor precum Java și C# în 1990 și începutul anilor 2000.

Cum pot fi explicate astfel de ipoteze optimiste? De fapt, Swift este conceput pentru programatorul obișnuit. Chiar și cele mai simple aplicații pot fi scrise în limbă, iar cu câteva instrumente destul de inteligente, limbajul oferă o modalitate eficientă de a învăța să scrii pe cont propriu. Dar principalul motiv pentru viitoarea popularitate a limbii se află în altă parte. Sute de mii de dezvoltatori creează astăzi aplicații pentru dispozitivele Apple folosind Objective-C. Dispozitivele Apple sunt foarte populare, ceea ce înseamnă că acești dezvoltatori vor continua să creeze aplicații pentru ele, dar în Swift, deoarece este mult mai bun și mai eficient decât Objective-C.

„Nu a existat un stimulent real pentru a utiliza Google Go”, spune Paul Jansen, care urmărește progresul diferitelor limbaje de programare de aproximativ cincisprezece ani. „Ceea ce îl face pe Swift diferit este stimulentul.”

Astăzi, GitHub, un depozit de dezvoltare open source popular, are peste 2.400 de proiecte folosind Swift. Merită să ne amintim că în acest moment limbajul este disponibil doar pentru un număr limitat de programatori.

Avantaje față de Objective-C

Pentru a abandona un limbaj în care au fost deja scrise mai multe produse și pentru a începe să învețe unul nou, programatorii au nevoie de motive foarte bune. Reînvățarea necesită timp și efort, iar până în prezent Chris Lattner este singura persoană cu patru ani de experiență în programare Swift. Cu toate acestea, aceste motive foarte convingătoare au fost deja prezentate.

Nu este că Swift este semnificativ mai atractiv decât alte limbaje, cum ar fi C#, Ruby sau Python, Swift este mult mai atractiv decât Objective-C, care cu greu poate fi numit un limbaj modern. Sintaxa Swift este mai familiară. Limbajul conține, de asemenea, mai multe instrumente de protecție împotriva erorilor și erorilor. Swift înțelege mai bine acțiunile codificatorului și își face munca mai eficientă, permițându-i să facă mai mult în mai puțin timp. Dar cel mai interesant aspect al limbii este așa-numitele Locuri de joacă.

Locuri de joacă

Locurile de joacă sunt concepute pentru a face programarea mai interactivă și mai accesibilă. Ideea este că atunci când un programator scrie cod pe o jumătate a ecranului, el vede rezultatul pe cealaltă jumătate. Astfel, puteți observa crearea programului în timp real. Când un programator face modificări la cod, acestea sunt făcute și în versiunea de rulare a programului, eliminând necesitatea compilărilor și repornirilor repetate.

Această abordare a scrierii codului nu numai că va ușura munca unui programator, ci va schimba modul în care gândim programarea, ducând-o la un nivel cu totul nou de înțelegere. De asemenea, Chris Lattner speră că, făcând codificarea mai ușoară și mai distractivă, va contribui la redefinirea modului în care este predată informatica astăzi.

Mai mult decât o limbă

Chris Lattner, creatorul Swift, supraveghează toate instrumentele pentru dezvoltatori Apple. Tot ceea ce este folosit pentru a crea programe pentru telefoane, tablete și computere Apple, atât de către dezvoltatori terți, cât și de către inginerii companiei. În calitate de student absolvent la Universitatea din Illinois, a creat un fel de instrument de dezvoltare numit LLVM, care este baza Xcode astăzi.

Apple a folosit LLVM pentru a schimba modul în care Objective-C a fost folosit pentru a crea aplicații. Acest lucru s-a întâmplat după ce Lattner s-a alăturat Apple în 2005, iar cinci ani mai târziu a folosit LLVM ca bază pentru Swift. Aceste două produse au fost special concepute pentru a funcționa în tandem. Cu alte cuvinte, Swift nu este doar o limbă, este o limbă care este strâns legată de tot ceea ce are nevoie un dezvoltator pentru a-și face treaba. Aceasta include nu numai mediul de dezvoltare integrat, ci și multe alte instrumente cu care fiecare dezvoltator Apple este deja familiarizat, cum ar fi depanatorul. Cu alte cuvinte, există motive pentru care zeci de mii de programatori ar trebui să scrie deja aplicații Swift.

Viteză

Acesta este exact cuvântul care caracterizează cel mai bine diferitele calități ale noii limbi Swift. Limbajul demonstrează o viteză uimitoare în conversia codului brut într-o aplicație executabilă. Viteza acestor aplicații pe telefoane și tablete ar trebui să fie surprinzătoare. Swift nu este doar prietenos cu oamenii, ci și prietenos cu computerul. Iar a treia calitate, despre care am vorbit deja, este viteza de răspândire.

Apple nu este prima companie care intră în acest ring. Are deja , Google și Mozilla. În anumite privințe, limbile acestor companii au mers mult mai departe, deoarece sunt deja folosite pentru munca internă. Mai mult, majoritatea sunt open source, ceea ce le face mai ușor de distribuit altor companii. Apple este cunoscut pentru controlul strâns asupra propriilor produse, iar codul este în prezent sursă închisă, ceea ce poate, de exemplu, îngreuna crearea de programe multiplatformă. Cu toate acestea, se crede că Swift va fi în cele din urmă open source.

Indiferent dacă Swift este open source sau nu, se preconizează că va avea o popularitate și rate de adoptare fără precedent. Unicitatea limbii, precum și popularitatea produselor Apple, își vor face, fără îndoială, treaba.

Bazat pe Wired

  • Serghei Savenkov

    un fel de recenzie „scurtă”... de parcă s-ar grăbi undeva