Initializers:
The signature includes the parameter names, so you can have two initializers, both taking the same types of parameters, as long as they have different names. eg.
init(withDouble: Double) {...}
init(withAnotherDouble: Double) {...}
And that's just fine.
Structs
Structs are *always* copied, so if you have a struct Foo with a property Bar:
struct Foo{var bar = 10}
let foo = Foo(bar: 100)
var foo2 = foo
then modify foo2:
foo2.bar = 99
println(foo.bar + " " + foo2.bar)
you get
100 99
Not really a gotcha, but if you don't declare your own initializers for a struct, and you have default values for all properties, then you get both an empty initializer
Foo() // bar will be 10
and a memberwise one
Foo(bar:100) // bar will be 100
Function Parameter names are not external by default
func aFunc(param: Int){...}
Cannot be called like this
aFunc(param:10)
You need to explicitly set an external name for the parameter, or use #
func aFunc(externalName param:Int){...}
or
func aFunc(#param:Int){...}
or call it without parameter names:
aFunc(10)
Class Initializers
Can be designated or convenience
Designated (init(...){...)})means that by the end of them, all properties will be set. Convenience(convenience init(...){...}) means that it'll only do a partial job.
Have rules about what can call what
Designated initializers *must* call a designated initializer from their super class
Convenience initializers *must* call another initializer in the same class
Convenience initializer *must* ultimately call a designated initializer.
Have rules about the order you do things
Designated initializers must first initialize properties in the current class, then call a designated initializer in the parent class, then they can change their inherited properties.
Convenience initializers must call other initializers first, before they assign any values to anything.
You cannot access self, read properties, or call any methods until all the properties have been initialized - ie. once the calls to other initializers have returned.
Can be inherited
If you have defaults for all your properties, and you don't declare any designated initializers yourself, then a sub class inherits all the parent's designated initializers.
If you have implementations - either automatically from above, or by creating them yourself - of all your parent's designated initializers, then you inherit all their convenience initializers too.
Is and As
is checks if something is an instance similar to instanceof/isInstanceOf[T])
as/as? performs a cast similar to (Float) or asInstanceOf[T] note that you can do this to a whole array in one go, you don't have to cast the individual elements:
let bar: AnyObject[] = ....
for foo in bar as SomeClass[] {println("SomeClass: '\(SomeClass.someProperty)'")}
These checks only work with protocols if you annotate that protocol with @objc which will have the side-effect that that protocol can only be applied to classes.
let bar: AnyObject[] = ....
for foo in bar as SomeClass[] {println("SomeClass: '\(SomeClass.someProperty)'")}
These checks only work with protocols if you annotate that protocol with @objc which will have the side-effect that that protocol can only be applied to classes.
Any/AnyObject
AnyObject is any instance of a class
Any is an instance of any type at all (except functions)