Hugo, a razão pela qual quero sair do FB é por ficar demasiado lento e consumir recursos passados 20min e se abrir um segundo projecto.
Att, António Pinto No dia 04/09/2014, às 17:28, Hugo Ferreira <[email protected]> escreveu: > APintex, > > Ainda não tinha pensado nisso mas é bem verdade. > > Eu mudei para o OS X à 2 anos e digo-te é sem V de volta. Todos os portáteis > baratos ou caros que passam pelas minhas mãos não chegam ao fim da garantia e > este é impecável. Nada a apontar. De tal forma que após acabar a garantia, > investi para duplicar a RAM e troquei o disco por um SSD e com garantia da > Apple. Digo-te que valeu cada cêntimo principalmente para o FB que abusa da > máquina. > > Por um lado gostaria de saír do FB. É um IDE preso no tempo :( mas por outro > lado serve o seu propósito e pelo que sondei, os outros não estão à altura. > > Eu uso o MySQL em paralelo com o SQL Server à uns anos. Ao fim de algum tempo > de conheceres bem os motores, consegues fazer SQL quase 100% compatível sem > um ORM (principalmente se usares SQL Server 2012+). > > Todos os projectos que faço, faço logo compatíveis com esses 2 motores. > > Para reports (que nenhum dev gosta) para AIR recomendo o único que conheço: > Stimulsoft mas é client-side. Podes usar uma app AIR via linha de comandos no > servidor para gerar reports como workaround se precisares de reports no lado > do servidor com PHP. > Têm um solução ASP.NET para quem usar este backend sem workarounds. > > Já disse no forum que se fizeram um solução HTML5 (puro) estou disposto a > pagar em avanço. Dizem que é algo que andam a pensar :) > > > 2014-09-04 17:17 GMT+01:00 APintex Gmail <[email protected]>: >> 2014 foi e está a ser um ano de mudanças… >> Passei do Windows para o OS X, quero passar do Flash Builder para o IntelliJ >> IDEA (ainda não tive coragem) >> Estou a refazer um projecto de .Net para AIR, de MSSQL para MySQL e >> webservices feitos em .Net para PHP. >> No meio disto tudo o que mais me custa são os reports (uma seca para mim >> desde sempre) >> >> António Pinto >> [email protected] >> >> >> >> No dia 04/09/2014, às 16:58, Hugo Ferreira <[email protected]> escreveu: >> >>> É como eu. Na realidade acredito que a maioria esteja no mesmo barco. Para >>> coisas a sério ainda não. >>> Quem já trabalha à anos com Objective-C, irá continuar mesmo após o Swift >>> se tornar uma realidade viável. >>> >>> Terminei o meu primeiro projecto HTML5 e correu muito bem. No final demorei >>> muito menos tempo do que previa e já tenho agora uma base para fazer o >>> próximo mais rapidamente. >>> >>> Quando houver tempo irei recriar um projecto em Flex com HTML5 e mais tarde >>> outro (se isto algum dia vier a acontecer) e depois disso acho que não >>> voltarei a usar o Flash ! >>> >>> O AIR vou continuar a usar e abusar e também muito código nativo com >>> Android. >>> >>> Também acho que o Swift será uma realidade para mim só para o ano que vem ! >>> >>> >>> 2014-09-04 16:48 GMT+01:00 Apintex <[email protected]>: >>>> Hugo, para já é pura curiosidade no Swift. Instalei o Xcode 6 beta e nem o >>>> abri. :( >>>> Vou vendo alguns exemplos para ir aprendendo alguma coisa e partilho com >>>> vocês os que acho importantes. >>>> Estou a terminar um projecto (MoneyEX Pro) e só no início do próximo ano >>>> começarei a trabalhar com o Swift. >>>> >>>> Att, >>>> >>>> António Pinto >>>> >>>> No dia 04/09/2014, às 16:10, Hugo Ferreira <[email protected]> >>>> escreveu: >>>> >>>>> APintex, >>>>> >>>>> Acabei à pouco tempo de ler 2 bons livros de desenvolvimento Android. >>>>> Já desenvolvi diversas ANE's para Android e já me sinto suficientemente >>>>> confortável para desenvolver qualquer app para Android ou mesmo ANE. >>>>> >>>>> Em breve gostaria de entrar no desenvolvimento nativo para iOS (tanto >>>>> apps como ANE's) e aqui ficam algumas dúvidas: >>>>> 1. Não faz sentido nesta altura do campeonato investigar em Objective-C >>>>> (thank you god); >>>>> 2. Será que não vale a pena esperar por um bom livro que seja uma >>>>> compilação do desenvolvimento Swift (de preferência em PT). Ainda não vi >>>>> nenhum na Fnac; >>>>> 3. Será que irá ser possível desenvolver ANE's com swift. Penso que aqui >>>>> a única coisa que falta é a lib que actualmente é para Objective-C (para >>>>> alguém transcrever tem de saber bem Objective-C) ou será possível usar a >>>>> actual ? >>>>> >>>>> As minhas expectativas são: >>>>> - Dentro de 1 ano o iOS8 tenha mais de 80% de market share para valer a >>>>> pena; >>>>> - Existam bons livros e exemplos; >>>>> - Exista um lib para Swift (a Adobe tem de fazer) ou ser possível usar a >>>>> actual (não sei); >>>>> - Exista uma framework para Bluetooth LE (para mim é importante) tal como >>>>> já existe com Objective-C ou se possa usar as actuais. >>>>> >>>>> >>>>> >>>>> 2014-09-04 15:58 GMT+01:00 APintex Gmail <[email protected]>: >>>>>> >>>>>> António Pinto >>>>>> [email protected] >>>>>> >>>>>> >>>>>> >>>>>> http://realm.io/news/swift-enums-pattern-matching-generics/ >>>>>> >>>>>> Sign up to be notified of future videos >>>>>> >>>>>> We won’t email you for any other reason, ever. >>>>>> >>>>>> Enums (0:40) >>>>>> >>>>>> Enums are a kind of abstraction that allow you to give a variable one >>>>>> value among several related values. For example, when building a state >>>>>> machine you could have an enum that describes the state of an object >>>>>> from a set number of states. There are three types of enums in Swift. >>>>>> >>>>>> Basic Enum (1:12) >>>>>> >>>>>> The most basic Swift enum simply has a bunch of cases and is declared >>>>>> using the enum key word. In this example, the enum is called Direction >>>>>> and can only be one of the four provided cases. To declare an enum, you >>>>>> use the enum name, followed by a dot and then one of the possible >>>>>> values. Unlike in Objective-C or C, enums are not typedefs of aliases >>>>>> for integers. >>>>>> >>>>>> enum Direction { >>>>>> case North >>>>>> case South >>>>>> case East >>>>>> case West >>>>>> } >>>>>> >>>>>> let myDirection = Direction.North >>>>>> Raw Value Enum (2:00) >>>>>> >>>>>> The second type of Swift enum is a “raw value” enum, which is the same >>>>>> as the basic enum but has additional raw values associated with each >>>>>> case. In this enum Title, each case has an associated string that is the >>>>>> name for the title. Important to note is that the raw value and the enum >>>>>> itself are not interchangeable. The toRaw and fromRaw methods help to go >>>>>> between the value and the enum. >>>>>> >>>>>> enum Title : String { >>>>>> case CEO = "Chief Executive Officer" >>>>>> case CTO = "Chief Technical Officer" >>>>>> case CFO = "Chief Financial Officer" >>>>>> } >>>>>> >>>>>> let myTitle = Title.CEO >>>>>> let myString : String = Title.CEO.toRaw() >>>>>> let anotherTitle : Title = >>>>>> Title.fromRaw("Chief Executive Officer")! >>>>>> For integer type raw enums, integer numbering remains implicit if you do >>>>>> not specify values. Swift automatically counts up from the last provided >>>>>> explicit value. This can be seen in the following example: >>>>>> >>>>>> enum Planet : Int { >>>>>> case Mercury = 1 >>>>>> case Venus, Earth, Mars // 2, 3, 4 >>>>>> case Jupiter = 100 >>>>>> case Saturn, Uranus, Neptune // 101, 102, 103 >>>>>> } >>>>>> Associated Value Enum (3:52) >>>>>> >>>>>> The third type of enum is one with associated values. Each case in the >>>>>> enum can carry associated data. In this example from the Swift book, the >>>>>> bar code enum allows you to associate different QR codes with different >>>>>> strings. >>>>>> >>>>>> enum Barcode { >>>>>> case UPCA(sys: Int, data: Int, check: Int) >>>>>> case QRCode(String) >>>>>> } >>>>>> >>>>>> let myUPC = >>>>>> Barcode.UPCA(sys: 0, data: 27917_01919, check: 2) >>>>>> let myQRCode = >>>>>> Barcode.QRCode("http://example.com") >>>>>> Associated values are especially useful in handling JSON, because arrays >>>>>> and dictionaries are actually types. Thus, you can create an enum to >>>>>> represent a JSON structure as a tree, with JSON nodes wrapping different >>>>>> types. >>>>>> >>>>>> enum JSONNode { >>>>>> case NullNode >>>>>> case StringNode(String) >>>>>> case NumberNode(Float) >>>>>> case BoolNode(Bool) >>>>>> case ArrayNode([JSONNode]) >>>>>> case ObjectNode([String:JSONNode]) >>>>>> } >>>>>> >>>>>> let x : JSONNode = .ArrayNode( >>>>>> [.NumberNode(10.0), >>>>>> .StringNode("hello"), >>>>>> .BoolNode(false)]) >>>>>> Switch Statements (Pattern Matching) (6:17) >>>>>> >>>>>> Switch statements is where most of the pattern matching functionality in >>>>>> Swift comes from. A basic switch statement looks very similar to an >>>>>> Objective-C switch statement, where there is a clause followed by cases. >>>>>> Two things to note: Swift switches don’t have breaks, so for old style >>>>>> fallthrough behaviour, your code must have an explicit use of the >>>>>> keyword fallthrough. Switch statements must also be comprehensive, so >>>>>> default cases are required, which may help prevent errors. >>>>>> >>>>>> let value = 10 >>>>>> switch value { >>>>>> case 10: println("ten") >>>>>> case 20: println("twenty") >>>>>> case 30: println("thirty") >>>>>> default: println("another number") >>>>>> } >>>>>> Ranges (8:35) >>>>>> >>>>>> In Swift, you can also pattern match on anything that’s comparable. You >>>>>> can even match strings now to a case (and printout emojis for a fun >>>>>> parlor trick!). Anything that can be compared with the double equals >>>>>> operator can be matched. Swift also allows matching on ranges, where >>>>>> ranges can be the pattern inside a switch state. >>>>>> >>>>>> let v: UInt = 10 >>>>>> switch v { >>>>>> case 0...9: println("Single digit") >>>>>> case 10...99: println("Double digits") >>>>>> case 100...999: println("Triple digits") >>>>>> default: println("4 or more digits") >>>>>> } >>>>>> Tuples (9:00) >>>>>> >>>>>> Tuples are composite data types - they contain multiple elements that >>>>>> can all be of different types. A tuple is then represented by the types >>>>>> of its elements. In this tuple-based switch statement, a tuple is the >>>>>> input. Each element in the pattern tuple is actually a sub-pattern, so >>>>>> you can match against patterns in each element. The underscore >>>>>> represents a “I don’t care” value. In this example, the last case >>>>>> functions as a default because the (_, _) says the same thing as a >>>>>> default - none of the other cases match, and we don’t care about other >>>>>> possible values. >>>>>> >>>>>> let person = ("Helen", 25) >>>>>> switch person { >>>>>> case ("Helen", let age): >>>>>> println("Your name is Helen, and you are \(age)" + " years old") >>>>>> case (_, 13...19): >>>>>> println("You are a teenager") >>>>>> case ("Bob", _): >>>>>> println("You are not a teenager, but your name" + " is Bob.") >>>>>> case (_, _): >>>>>> println("no comment") >>>>>> } >>>>>> Binding in Cases (10:56) >>>>>> >>>>>> If you have case statements, there may be associated data that needs to >>>>>> be used in the case statement body. The let binding is how you can do >>>>>> that. The first two cases in this example take the tuple elements and >>>>>> create the bindings X and Y to represent those elements. >>>>>> >>>>>> let myTuple = ("abcd", 1234) >>>>>> switch myTuple { >>>>>> case let (x, y): >>>>>> "The string in 'x' is \(x); " + "the integer in 'y' is \(y)" >>>>>> case (let x, let y): >>>>>> "Another way to do the exact same thing" >>>>>> case (_, let y): >>>>>> "We don't care about the string in 'x', " + "but the integer in 'y' is >>>>>> \(y)" >>>>>> } >>>>>> Enums (12:22) >>>>>> >>>>>> You can also switch on enums, but for enums with values wrapped inside, >>>>>> switch statements are the only way you can access those values. The >>>>>> following switch statement uses let to bind each case and use the value. >>>>>> >>>>>> enum ParseResult { >>>>>> case NumericValue(Int) >>>>>> case Error(String) >>>>>> } >>>>>> >>>>>> let a = ParseResult.NumericValue(1) >>>>>> switch a { >>>>>> case let .NumericValue(v): >>>>>> "Success; numeric value is \(v)" >>>>>> case .Error(let err): >>>>>> "Failed; error message is \(err)" >>>>>> } >>>>>> Types (13:20) >>>>>> >>>>>> The main type of switch is the type/sub-class pattern. If your switch >>>>>> conditional in this clause is a class, then class will have sub- or >>>>>> superclasses. In this example, the UIView is matched against the >>>>>> different possible types of views: UIImageView, UILabel, and >>>>>> UITableView. The “as” keyword differs from the “is” keyword in that “as” >>>>>> allows you to use the let binding and do something with myView, while >>>>>> “is” is used simply to check the type. >>>>>> >>>>>> let myView : UIView = getView() >>>>>> switch myView { >>>>>> case is UIImageView: >>>>>> println("It's an image view") >>>>>> case let lbl as UILabel: >>>>>> println("It's a label, with text \(lbl.text)") >>>>>> case let tv as UITableView: >>>>>> println("It's a table view, with"+ " \(tv.numberOfSections()) >>>>>> sections") >>>>>> default: >>>>>> println("It's some other type of view") >>>>>> } >>>>>> where clause (14:33) >>>>>> >>>>>> Another important thing about switch statements is the where cause. This >>>>>> clause can be added to any case and acts as a boolean expression that >>>>>> returns true or false. The case is then taken only if this where clause >>>>>> returns true. This switch example relies not on pattern matching but >>>>>> instead on these where clauses, following through with the case if >>>>>> myView is of a certain size or other characteristic. >>>>>> >>>>>> let myView : UIView = getView() >>>>>> switch myView { >>>>>> case _ where myView.frame.size.height < 50: >>>>>> println("Your view is shorter than 50 units") >>>>>> case _ where myView.frame.size.width > 20: >>>>>> println("Your view is at least 50 units tall," + " and is more than 20 >>>>>> units wide") >>>>>> case _ where >>>>>> myView.backgroundColor == UIColor.greenColor(): >>>>>> println("Your view is at least 50 units tall," + " at most 20 units >>>>>> wide, and is green.") >>>>>> default: >>>>>> println("I can't describe your view.") >>>>>> } >>>>>> Expression Operator (15:28) >>>>>> >>>>>> A final important feature in Swift is the expression operator. >>>>>> >>>>>> func ~=(pattern: Type1, value: Type2) -> Bool >>>>>> This operator takes the pattern and the value, and then uses pattern >>>>>> matching to return true or false. It can be overloaded as well to >>>>>> implement custom matching behaviour. The following piece of code is >>>>>> Swift pseudo-code to demonstrate what you could build. In an array four >>>>>> elements long, you could create cases that matched any combination of >>>>>> the elements. >>>>>> >>>>>> let myArray = [1, 2, 4, 3] >>>>>> switch myArray { >>>>>> case [..., 0, 0, 0]: >>>>>> doSomething() >>>>>> case [4, ...]: >>>>>> doSomething() >>>>>> case [_, 2, _, 4]: >>>>>> doSomething() >>>>>> case [_, _, 3, _]: >>>>>> doSomething() >>>>>> case [_, _, _, 3]: >>>>>> doSomething() >>>>>> default: >>>>>> doDefault() >>>>>> } >>>>>> Expression Patterns (17:42) >>>>>> >>>>>> The following extended example is a custom implementation of the pattern >>>>>> match operator. This custom operator turns the elements of an array into >>>>>> the enum values. >>>>>> >>>>>> enum WCEnum { >>>>>> case Wildcard >>>>>> case FromBeginning >>>>>> case ToEnd >>>>>> case Literal(Int) >>>>>> } >>>>>> >>>>>> func ~=(pattern: [WCEnum], value: [Int]) -> Bool { >>>>>> var ctr = 0 >>>>>> for currentPattern in pattern { >>>>>> if ctr >= value.count || ctr < 0 { return false } >>>>>> let currentValue = value[ctr] >>>>>> switch currentPattern { >>>>>> case .Wildcard: ctr++ >>>>>> case .FromBeginning where ctr == 0: >>>>>> ctr = (value.count - pattern.count + 1) >>>>>> case .FromBeginning: return false >>>>>> case .ToEnd: return true >>>>>> case .Literal(let v): >>>>>> if v != currentValue { return false } >>>>>> else { ctr++ } >>>>>> } >>>>>> } >>>>>> return true >>>>>> } >>>>>> Protocols (21:06) >>>>>> >>>>>> In order to understand generics, you have to understand protocols, which >>>>>> are something that existed in Objective-C as well. Protocols are >>>>>> basically a contract that can define nothing at all or any number of >>>>>> methods and properties. However, protocols can’t have any implementation >>>>>> details - they can only have method signatures and property names. >>>>>> MyProtocol in this code defines just one property as requiring a getter >>>>>> and setter, as well as one method. >>>>>> >>>>>> protocol MyProtocol { >>>>>> var someProperty : Int { get set } >>>>>> func barFunc (x: Int, y: Int) -> String >>>>>> } >>>>>> Types can conform to none, one, or multiple protocols. Protocols can >>>>>> also inherit from other protocols, thereby getting all the parent >>>>>> protocol’s methods and properties. >>>>>> >>>>>> Conformance (23:18) >>>>>> >>>>>> With protocols, you can make classes, structs, and enums conform to >>>>>> them. By making a type conform to a protocol, you are telling the >>>>>> compiler that your type will match the definitions set in the protocol. >>>>>> MyClass conforms to MyProtocol in providing implementations that match. >>>>>> >>>>>> class MyClass { >>>>>> // Nothing here... >>>>>> // This won't compile! >>>>>> } >>>>>> >>>>>> class MyClass : MyProtocol { >>>>>> var myProperty : Int = 0 >>>>>> // Property conformance >>>>>> func barFunc (x: Int, y: Int) -> String { >>>>>> return "\(x) + \(y) = \(x + y)" >>>>>> } >>>>>> var someProperty : Int { >>>>>> get { >>>>>> return myProperty >>>>>> } >>>>>> set { >>>>>> myProperty = newValue >>>>>> } >>>>>> } >>>>>> } >>>>>> Uses (24:06) >>>>>> >>>>>> There are a few reasons you may want to use protocols. The first reason >>>>>> is parent-child relationships, where you don’t want all the children to >>>>>> have a specific class of a parent. For example, UITableView comes with >>>>>> Cocoa and is a list of objects that specifies the number and content of >>>>>> cells. For the delegate to provide that information, it just has to >>>>>> implement the protocol which has methods for the cells. This way, you >>>>>> can avoid specifying the delegate as a sub-class of a class. >>>>>> >>>>>> A second major use for protocols can be seen in the Swift Standard >>>>>> Library, where they add functionality to a type, piece by piece. >>>>>> Equatable, LogicValue, and AbsoluteValuable are all protocols that are >>>>>> implemented by different types in the library. The LogicValue protocol >>>>>> has a method that takes an object and turns it into true or false, so if >>>>>> you create a custom type and implement this protocol, you can use that >>>>>> type in an if statement’s clause. >>>>>> >>>>>> One final use for protocols is to allow different types to be described >>>>>> by the same generic type parameter. For example, if you wanted to put >>>>>> different types into an array, you could give the objects a protocol and >>>>>> then declare the array with the protocol. You then have an array of >>>>>> equatables and anything that conforms to the equatable in that array can >>>>>> be added. >>>>>> >>>>>> protocol JSONType { } >>>>>> extension String : JSONType { } >>>>>> extension Float : JSONType { } >>>>>> extension Bool : JSONType { } >>>>>> extension Array : JSONType { } >>>>>> extension Dictionary : JSONType { } >>>>>> >>>>>> let b : Array<JSONType> = [10.1, 10.2, "foo"] >>>>>> let a : Array<JSONType> = [10.0, "bar", false, b] >>>>>> Generics (28:36) >>>>>> >>>>>> Generics did not exist in Objective-C. THey are basically the statically >>>>>> typed languages’ answer to the flexibility of dynamically typed >>>>>> languages. Generics are used to allow you to use the same code for >>>>>> different types. The type parameter allows you to do this generically. >>>>>> >>>>>> func swapItems<T>(inout this: T, inout that: T) { >>>>>> let tempThis = this >>>>>> this = that >>>>>> that = tempThis >>>>>> } >>>>>> With generics, you can also enforce more constraints, as in the >>>>>> following example. The “: Equatable” allows you to constrain T to any >>>>>> type that conforms to Equatable, or is valid with the double equals >>>>>> operator. >>>>>> >>>>>> func firstAndLastAreEqual<T : Equatable> >>>>>> (someArray: Array<T>) -> Bool { >>>>>> let first = someArray[0] >>>>>> let last = someArray[someArray.count - 1] >>>>>> return first == last >>>>>> } >>>>>> You can also use generics for either functions or type declarations. >>>>>> Type information is available at runtime, which is helpful. The compiler >>>>>> can optimize by creating specific versions for each type that’s being >>>>>> used (like C++ templates), but it can also fall back to the generic >>>>>> implementation. >>>>>> >>>>>> Extended Example (33:56) >>>>>> >>>>>> In the extended example, the goal was to create a function that was >>>>>> typesafe and could handle every case that involved the following types: >>>>>> Array, Dictionary, SquareMatrix, TreeNode. The function was to take a >>>>>> collection of one of the above types, take an array, and append the >>>>>> items in that collection to the array. >>>>>> >>>>>> A protocol was defined to specify that a type can give back all of the >>>>>> elements inside of it. You have containers that can implement >>>>>> “AllElements”. On a generic level, you might need to know the type of >>>>>> the elements inside the collection, and so a wildcard is called >>>>>> “ElementType”. And so, you specify the element type when you implement >>>>>> the function itself. >>>>>> >>>>>> protocol AllElements { >>>>>> typealias ElementType >>>>>> // Return an array containing all the objects >>>>>> // in the collection >>>>>> func allElements() -> Array<ElementType> >>>>>> } >>>>>> Another thing you can use is the NilLiteral protocol, the point of which >>>>>> is to take nil and turn it into something equivalent to nil in that >>>>>> type. For an int, it would return 0, or maybe for a string, it would >>>>>> return “”. In the following example, you would want it to return >>>>>> something of type self. >>>>>> >>>>>> protocol NilLiteralConvertible { >>>>>> class func convertFromNilLiteral() -> Self >>>>>> } >>>>>> Extensions then add methods, computed properties, and protocol >>>>>> conformance to existing types. Array and SquareMatrix are both fairly >>>>>> straightforward - you just return the arrays themselves. For the >>>>>> Dictionary, you iterate through all the elements, create a buffer, and >>>>>> return it with the elements inside. Finally, for the tree, you go >>>>>> through the tree in a recursive traversal and again add the elements to >>>>>> a buffer. >>>>>> >>>>>> Put together, the final function appendToArray calls AllElements and >>>>>> gives “a”, which is an array with all the elements on the source. Then >>>>>> each of those elements is just added to the array in “dest”. This works >>>>>> because the generic argument “T” has to implement AllElements, and U has >>>>>> been constrained to the same type as T. The where clause is included in >>>>>> case you want to do more than have this type implement one protocol. >>>>>> Before the where, you declare type arguments, which can conform to >>>>>> either one or none protocols. If you want T to conform to 2+ protocols, >>>>>> add a “where” clause to constrain. You can then constrain any free type >>>>>> arguments you declared earlier and any associated types associated with >>>>>> the type arguments via protocols (e.g. T.SomeType). >>>>>> >>>>>> func appendToArray >>>>>> <T: AllElements, U where U == T.ElementType> >>>>>> (source: T, inout dest: Array<U>) { >>>>>> >>>>>> let a = source.allElements() >>>>>> for element in a { >>>>>> dest.append(element) >>>>>> } >>>>>> } >>>>>> >>>>>> var buffer = ["a", "b", "c"] >>>>>> appendToArray([1: "foo", 2: "bar"], &buffer) >>>>>> Now you’ve created five methods for this one process. In actuality, you >>>>>> would have your containers implement Sequence and use a for-in loop to >>>>>> go through all the elements. This requires knowledge of Generators, >>>>>> EnumerateGenerators, and other material. >>>>>> >>>>>> Q&A (46:05) >>>>>> >>>>>> Q: In the extension example, are we extending all arrays of anything? >>>>>> Austin: Yes, which is why this is a bad idea in practice. You can’t >>>>>> actually say that you only want arrays with JSON type objects to also >>>>>> implement JSON array, which is needed to ensure that you have valid JSON. >>>>>> >>>>>> Q: Is the type T built-in? Where does it come from? >>>>>> Austin: T is actually coming from the declaration of array. If you >>>>>> command-click an array in XCode, the declaration of the array shows that >>>>>> it declares a generic argument T that has some constraints. >>>>>> >>>>>> Q: Is there any kind of trace for generics and the way it works? Is it >>>>>> traceable to an existing language or is it brand-new? >>>>>> Austin: I don’t know the answer, but I’m sure there are precedents. >>>>>> Generics in Swift kind of de-emphasize object oriented programming >>>>>> because they’re built more around protocols than around class >>>>>> hierarchies. You might get a closer procedent if you looked at Haskell. >>>>>> >>>>>> Q: What is the exclamation point used for? >>>>>> Austin: The exclamation mark is for optionals. Everything in Swift is >>>>>> non-nilable by default, so if you want to set something to nil, it must >>>>>> be declared as an optional. The question mark after the type signifies >>>>>> this. Then, the exclamation mark, or bang, takes the value out of the >>>>>> optional so you can use it. >>>>>> >>>>>> Q: Is there something like value template parameters in Swift? Or should >>>>>> we just type in, type template? >>>>>> Austin: I don’t think so, I don’t think Swift generics are as powerful. >>>>>> >>>>>> Q: Can you explain let? It seemed like it would sometimes check the case >>>>>> and othertimes it would set it to the constant. >>>>>> Austin: A let pattern kind of matches everything, but also takes a value >>>>>> and puts it in the constant for later use. When we use “as”, it both >>>>>> checks the type and also puts it in the constant. >>>>>> >>>>>> Sign up to be notified of future videos >>>>>> >>>>>> We won’t email you for any other reason, ever. >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da >>>>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do >>>>>> Grupos do Google. >>>>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, >>>>>> envie um email para [email protected]. >>>>>> Para publicar uma mensagem neste grupo, envie um email para >>>>>> [email protected]. >>>>>> Visite este grupo em http://groups.google.com/group/riapt. >>>>>> Para mais opções, visite https://groups.google.com/d/optout. >>>>> >>>>> >>>>> -- >>>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da >>>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do >>>>> Grupos do Google. >>>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, >>>>> envie um email para [email protected]. >>>>> Para publicar uma mensagem neste grupo, envie um email para >>>>> [email protected]. >>>>> Visite este grupo em http://groups.google.com/group/riapt. >>>>> Para mais opções, visite https://groups.google.com/d/optout. >>>> >>>> >>>> -- >>>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da >>>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do >>>> Grupos do Google. >>>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, >>>> envie um email para [email protected]. >>>> Para publicar uma mensagem neste grupo, envie um email para >>>> [email protected]. >>>> Visite este grupo em http://groups.google.com/group/riapt. >>>> Para mais opções, visite https://groups.google.com/d/optout. >>> >>> >>> -- >>> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da >>> Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" do >>> Grupos do Google. >>> Para anular a subscrição deste grupo e parar de receber emails do mesmo, >>> envie um email para [email protected]. >>> Para publicar uma mensagem neste grupo, envie um email para >>> [email protected]. >>> Visite este grupo em http://groups.google.com/group/riapt. >>> Para mais opções, visite https://groups.google.com/d/optout. >> >> -- >> Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da Comunidade >> Portuguesa de Rich Internet Applications - www.riapt.org" do Grupos do >> Google. >> Para anular a subscrição deste grupo e parar de receber emails do mesmo, >> envie um email para [email protected]. >> Para publicar uma mensagem neste grupo, envie um email para >> [email protected]. >> Visite este grupo em http://groups.google.com/group/riapt. >> Para mais opções, visite https://groups.google.com/d/optout. > > -- > Recebeu esta mensagem porque subscreveu ao grupo "Mailing List da Comunidade > Portuguesa de Rich Internet Applications - www.riapt.org" do Grupos do Google. > Para anular a subscrição deste grupo e parar de receber emails do mesmo, > envie um email para [email protected]. > Para publicar uma mensagem neste grupo, envie um email para > [email protected]. > Visite este grupo em http://groups.google.com/group/riapt. > Para mais opções, visite https://groups.google.com/d/optout. -- Recebeu esta mensagem porque está inscrito no grupo "Mailing List da Comunidade Portuguesa de Rich Internet Applications - www.riapt.org" dos Grupos do Google. Para anular a subscrição deste grupo e parar de receber emails do mesmo, envie um email para [email protected]. Para publicar uma mensagem neste grupo, envie um e-mail para [email protected]. Visite este grupo em http://groups.google.com/group/riapt. Para mais opções, consulte https://groups.google.com/d/optout.
