:) Hugo, o meu MB Pro tem 16Gb e SSD 500Gb... tenho sempre montes de app abertas (XAMPP, FB, MySQLWorkbench, vários Sublime text com PHP, Dash, Mail, Safari com n pág abertas, para não falar em skypes e companhia). Dá para tudo e nunca se queixou eheheh...
António Pinto [email protected] No dia 04/09/2014, às 18:26, Hugo Ferreira <[email protected]> escreveu: > APintex, > > Conheco perfeitamente o sintoma à alguns anos. Também existe um problema que > começa a dar um erro no FB (reportado por mim à muito tempo e com muitos > requests e também sem correcção). O workaround é fechar e voltar a abrir ! > > Posso te dizer que antes com 4 GB ram e disco normal, demorava vários > segundos a arrancar o OS, muitos segundos a abrir o FB e era impensável ter > uma outra app aberta que consumi-se mais do que alguns dezenas de MB de RAM. > > Agora com 8 GB ram + disco SSD, demora 2 segundos a ter o OS totalmente > pronto, o FB deve demorar uns 3-4 segundos a estar operacional e é possível > ter outro programa aberto (Eclipse, VirtualBox com 2 GB ram dedicado !). > > Não sei se foi apenas da ram, disco ou tudo junto mas fica a nota. > > > > > > 2014-09-04 18:22 GMT+01:00 Apintex <[email protected]>: > 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 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.
