Optional
An Optional is just an enum
enum Optional<T> { // the <T> is the generic like as in Array<T>
case None
case Some(T)
}
e.g.
-
let x: String? = nil
<=>let x = Optional<String>.None
-
let x: String? = "hello"
<=>let x = Optional<String>.Some("hello")
-
var y = x!
<=>
switch x {
case Some(let value): y = value
case None: // raise an exception
}
- if let
let x: String? = ...
if let y = x {
// do something with y
}
<=>
switch x {
case .Some(let y):
// do something with y
case .None:
break
}
Optionals can be "chained"
var display: UILabel?
if let label = display {
if let text = label.text {
let x = text.hashValue
...
}
}
can be written as below, which is much nicer
if let x = display?.text?.hashValue{ ... }
There is also an Optional "default" operator ??
What if we want to put a String into a UILabel, but if it is nil, put " " (space) in that UILabel?
let s: String? ... // might be nil
if s != nil {
display.text = s
} else {
display.text = " "
}
... can be expressed much more simply this way ...
display.text = s ?? " "
Tuples
A type out of other types by grouping them
e.g.
let x: (String, Int, Double) = ("hello", 5, 0.85)
let (word, number, value) = x // tuple elements named when accessing the tuple
print(word) // prints hello
print(number) // prints 5
... or tuple elements can be named when the tuple is declared ...
let x: (w: String, n: Int, v: Double) = ("hello", 5, 0.85)
print(x.w) // prints hello
print(x.n) // prints 5
renames the tuple's elements on access
let (wrd, num, val) = x
Range
A range in Swift is just two end points
Range is generic (e.g. Range<T>)
pseudo-representation of Range:
struct Range<T> {
var startIndex: T
var endIndex: T
}
An array's range would be a Range<Int>
Warning: A String's subrange is not Range<Int>, it's Range<String.Index>
e.g.
let array = ["a", "b", "c", "d"]
let subArray1 = array[2...3] // ["c", "d"]
let subArray2 = array[2..<3] // ["c"]
for i in 1...10 {}
Data Structure in Swift
Classes, Structures, Enumerations
These are the 3 fundamental building blocks of data structures in Swift
Similarities
- Declaration syntax ...
class CalculatorBrain {
}
struct Vertex {
}
enum Operation {
}
- Properties and Functions
- Initializers (not enum)
Differences
- Inheritance (class only)
- Value type (struct, enum) vs. Reference type (class)
- struct and enum are passed around by value
- class pass pointers around listed in heap
Value vs. Reference
Value
- Copied when passed as an argument to a function
- Function parameters are constant
- any
func
that can mutate a struct/enum with key wordmutating
Reference
- Stored in heap and reference counted (automatically)
- Constant pointers to a class (
let
) still can mutate by calling methods and changing properties - When passed as an argument, does not make a copy (just passing a pointer)
Array
Interesting Array<T> methods
- Filter method: filter any "undesirables" out
filter(includeElement: (T) -> Bool) -> [T]
let bigNumbers = [2,3,15,20,9].filter({ $0 > 10 }) //bigNumbers = [15,20]
- map take the closure, which converts each element in the array to something else.
map(transform: (T) -> U) -> [U]
let intToString: [String] = [1,2,3].map { String($0) }
- Reduce an entire array to a single value
reduce(initial: U, combine: (U, T) -> U) -> U
let sum: Int = [1,2,3].reduce(0) { $0+$1 } //adds up all elements in the array
Dictionary
- use a tuple with for-in to enumerate a Dictionary
for (key, value) in pac10teamRankings {
print("\(key) = \(value)")
}
String
- The simplest way to deal with the characters in a string is via this property
var characters: String.CharacterView { get }
- Other String Methods
- startIndex -> String.Index
- endIndex -> String.Index
- hasPrefix(String) -> Bool
- hasSuffix(String) -> Bool
- capitalizedString -> String
- lowercaseString -> String
- uppercaseString -> String
- componentsSeparatedByString(String) -> [String]
//"1,2,3".csbs(",") = ["1","2","3"]
Initialization
- There are two types of inits in a class: convenience and designated
- A designated init must (and can only) call a designated init that is in the immediate superclass.
- Before calling a superclass's init, you must initialize all properties introduced by your class
- Before you assign a value to an inherited property, you must call a superclass's init.
- A convenience init must (and can only) call an init in its own class.
- A convenience init must call that init before it can set any property values.
AnyObject
- Optional Conversion with
as?
let ao: AnyObject = ...
if let foo = ao as? SomeClass {
// we can use foo and know that it is of type SomeClass in here
}
欢迎转载,转载请注明出处。访问我的个人主页,查看更多。