mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-08-21 22:05:46 +02:00
Merge remote-tracking branch 'adambard/master'
Conflicts: swift.html.markdown
This commit is contained in:
@@ -3,6 +3,10 @@ language: swift
|
||||
contributors:
|
||||
- ["Grant Timmerman", "http://github.com/grant"]
|
||||
- ["Christopher Bess", "http://github.com/cbess"]
|
||||
- ["Joey Huang", "http://github.com/kamidox"]
|
||||
- ["Anthony Nguyen", "http://github.com/anthonyn60"]
|
||||
- ["Clayton Walker", "https://github.com/cwalk"]
|
||||
- ["Fernando Valverde", "http://visualcosita.xyz"]
|
||||
filename: learnswift.swift
|
||||
---
|
||||
|
||||
@@ -10,7 +14,7 @@ Swift is a programming language for iOS and OS X development created by Apple. D
|
||||
|
||||
The official [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) book from Apple is now available via iBooks.
|
||||
|
||||
See also Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/LandingPage/index.html), which has a complete tutorial on Swift.
|
||||
See also Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), which has a complete tutorial on Swift.
|
||||
|
||||
```swift
|
||||
// import a module
|
||||
@@ -22,10 +26,13 @@ import UIKit
|
||||
|
||||
// Xcode supports landmarks to annotate your code and lists them in the jump bar
|
||||
// MARK: Section mark
|
||||
// MARK: - Section mark with a separator line
|
||||
// TODO: Do something soon
|
||||
// FIXME: Fix this code
|
||||
|
||||
println("Hello, world")
|
||||
// In Swift 2, println and print were combined into one print method. Print automatically appends a new line.
|
||||
print("Hello, world") // println is now print
|
||||
print("Hello, world", appendNewLine: false) // printing without appending a newline
|
||||
|
||||
// variables (var) value can change after being set
|
||||
// constants (let) value can NOT be changed after being set
|
||||
@@ -45,16 +52,17 @@ let piText = "Pi = \(π), Pi 2 = \(π * 2)" // String interpolation
|
||||
// Build Specific values
|
||||
// uses -D build configuration
|
||||
#if false
|
||||
println("Not printed")
|
||||
print("Not printed")
|
||||
let buildValue = 3
|
||||
#else
|
||||
let buildValue = 7
|
||||
#endif
|
||||
println("Build value: \(buildValue)") // Build value: 7
|
||||
print("Build value: \(buildValue)") // Build value: 7
|
||||
|
||||
/*
|
||||
Optionals are a Swift language feature that allows you to store a `Some` or
|
||||
`None` value.
|
||||
Optionals are a Swift language feature that either contains a value,
|
||||
or contains nil (no value) to indicate that a value is missing.
|
||||
A question mark (?) after the type marks the value as optional.
|
||||
|
||||
Because Swift requires every property to have a value, even nil must be
|
||||
explicitly stored as an Optional value.
|
||||
@@ -68,13 +76,19 @@ var someOptionalString2: Optional<String> = "optional"
|
||||
if someOptionalString != nil {
|
||||
// I am not nil
|
||||
if someOptionalString!.hasPrefix("opt") {
|
||||
println("has the prefix")
|
||||
print("has the prefix")
|
||||
}
|
||||
|
||||
|
||||
let empty = someOptionalString?.isEmpty
|
||||
}
|
||||
someOptionalString = nil
|
||||
|
||||
/*
|
||||
Trying to use ! to access a non-existent optional value triggers a runtime
|
||||
error. Always make sure that an optional contains a non-nil value before
|
||||
using ! to force-unwrap its value.
|
||||
*/
|
||||
|
||||
// implicitly unwrapped optional
|
||||
var unwrappedString: String! = "Value is expected."
|
||||
// same as above, but ! is a postfix operator (more syntax candy)
|
||||
@@ -89,13 +103,13 @@ if let someOptionalStringConstant = someOptionalString {
|
||||
|
||||
// Swift has support for storing a value of any type.
|
||||
// AnyObject == id
|
||||
// Unlike Objective-C `id`, AnyObject works with any value (Class, Int, struct, etc)
|
||||
// Unlike Objective-C `id`, AnyObject works with any value (Class, Int, struct, etc.)
|
||||
var anyObjectVar: AnyObject = 7
|
||||
anyObjectVar = "Changed value to a string, not good practice, but possible."
|
||||
|
||||
/*
|
||||
Comment here
|
||||
|
||||
|
||||
/*
|
||||
Nested comments are also supported
|
||||
*/
|
||||
@@ -116,6 +130,7 @@ shoppingList[1] = "bottle of water"
|
||||
let emptyArray = [String]() // let == immutable
|
||||
let emptyArray2 = Array<String>() // same as above
|
||||
var emptyMutableArray = [String]() // var == mutable
|
||||
var explicitEmptyMutableStringArray: [String] = [] // same as above
|
||||
|
||||
|
||||
// Dictionary
|
||||
@@ -127,6 +142,7 @@ occupations["Jayne"] = "Public Relations"
|
||||
let emptyDictionary = [String: Float]() // let == immutable
|
||||
let emptyDictionary2 = Dictionary<String, Float>() // same as above
|
||||
var emptyMutableDictionary = [String: Float]() // var == mutable
|
||||
var explicitEmptyMutableDictionary: [String: Float] = [:] // same as above
|
||||
|
||||
|
||||
//
|
||||
@@ -137,21 +153,21 @@ var emptyMutableDictionary = [String: Float]() // var == mutable
|
||||
let myArray = [1, 1, 2, 3, 5]
|
||||
for value in myArray {
|
||||
if value == 1 {
|
||||
println("One!")
|
||||
print("One!")
|
||||
} else {
|
||||
println("Not one!")
|
||||
print("Not one!")
|
||||
}
|
||||
}
|
||||
|
||||
// for loop (dictionary)
|
||||
var dict = ["one": 1, "two": 2]
|
||||
for (key, value) in dict {
|
||||
println("\(key): \(value)")
|
||||
print("\(key): \(value)")
|
||||
}
|
||||
|
||||
// for loop (range)
|
||||
for i in -1...shoppingList.count {
|
||||
println(i)
|
||||
print(i)
|
||||
}
|
||||
shoppingList[1...2] = ["steak", "peacons"]
|
||||
// use ..< to exclude the last number
|
||||
@@ -164,7 +180,7 @@ while i < 1000 {
|
||||
|
||||
// do-while loop
|
||||
do {
|
||||
println("hello")
|
||||
print("hello")
|
||||
} while 1 == 2
|
||||
|
||||
// Switch
|
||||
@@ -221,8 +237,8 @@ let pricesTuple = getGasPrices()
|
||||
let price = pricesTuple.2 // 3.79
|
||||
// Ignore Tuple (or other) values by using _ (underscore)
|
||||
let (_, price1, _) = pricesTuple // price1 == 3.69
|
||||
println(price1 == pricesTuple.1) // true
|
||||
println("Gas price: \(price)")
|
||||
print(price1 == pricesTuple.1) // true
|
||||
print("Gas price: \(price)")
|
||||
|
||||
// Named tuple params
|
||||
func getGasPrices2() -> (lowestPrice: Double, highestPrice: Double, midPrice: Double) {
|
||||
@@ -260,7 +276,7 @@ func swapTwoInts(inout a: Int, inout b: Int) {
|
||||
var someIntA = 7
|
||||
var someIntB = 3
|
||||
swapTwoInts(&someIntA, &someIntB)
|
||||
println(someIntB) // 7
|
||||
print(someIntB) // 7
|
||||
|
||||
|
||||
//
|
||||
@@ -301,10 +317,10 @@ print(numbers) // [3, 6, 18]
|
||||
// MARK: Structures
|
||||
//
|
||||
|
||||
// Structures and classes have very similar capabilites
|
||||
// Structures and classes have very similar capabilities
|
||||
struct NamesTable {
|
||||
let names = [String]()
|
||||
|
||||
|
||||
// Custom subscript
|
||||
subscript(index: Int) -> String {
|
||||
return names[index]
|
||||
@@ -314,7 +330,7 @@ struct NamesTable {
|
||||
// Structures have an auto-generated (implicit) designated initializer
|
||||
let namesTable = NamesTable(names: ["Me", "Them"])
|
||||
let name = namesTable[1]
|
||||
println("Name is \(name)") // Name is Them
|
||||
print("Name is \(name)") // Name is Them
|
||||
|
||||
//
|
||||
// MARK: Classes
|
||||
@@ -335,7 +351,7 @@ public class Shape {
|
||||
|
||||
internal class Rect: Shape {
|
||||
var sideLength: Int = 1
|
||||
|
||||
|
||||
// Custom getter and setter property
|
||||
private var perimeter: Int {
|
||||
get {
|
||||
@@ -346,16 +362,16 @@ internal class Rect: Shape {
|
||||
sideLength = newValue / 4
|
||||
}
|
||||
}
|
||||
|
||||
// Computed properties must be declared as `var`, you know, cause they can change
|
||||
|
||||
// Computed properties must be declared as `var`, you know, cause' they can change
|
||||
var smallestSideLength: Int {
|
||||
return self.sideLength - 1
|
||||
}
|
||||
|
||||
|
||||
// Lazily load a property
|
||||
// subShape remains nil (uninitialized) until getter called
|
||||
lazy var subShape = Rect(sideLength: 4)
|
||||
|
||||
|
||||
// If you don't need a custom getter and setter,
|
||||
// but still want to run code before and after getting or setting
|
||||
// a property, you can use `willSet` and `didSet`
|
||||
@@ -365,19 +381,19 @@ internal class Rect: Shape {
|
||||
print(someIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init(sideLength: Int) {
|
||||
self.sideLength = sideLength
|
||||
// always super.init last when init custom properties
|
||||
super.init()
|
||||
}
|
||||
|
||||
|
||||
func shrink() {
|
||||
if sideLength > 0 {
|
||||
--sideLength
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override func getArea() -> Int {
|
||||
return sideLength * sideLength
|
||||
}
|
||||
@@ -400,7 +416,36 @@ let aShape = mySquare as Shape
|
||||
|
||||
// compare instances, not the same as == which compares objects (equal to)
|
||||
if mySquare === mySquare {
|
||||
println("Yep, it's mySquare")
|
||||
print("Yep, it's mySquare")
|
||||
}
|
||||
|
||||
// Optional init
|
||||
class Circle: Shape {
|
||||
var radius: Int
|
||||
override func getArea() -> Int {
|
||||
return 3 * radius * radius
|
||||
}
|
||||
|
||||
// Place a question mark postfix after `init` is an optional init
|
||||
// which can return nil
|
||||
init?(radius: Int) {
|
||||
self.radius = radius
|
||||
super.init()
|
||||
|
||||
if radius <= 0 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var myCircle = Circle(radius: 1)
|
||||
print(myCircle?.getArea()) // Optional(3)
|
||||
print(myCircle!.getArea()) // 3
|
||||
var myEmptyCircle = Circle(radius: -1)
|
||||
print(myEmptyCircle?.getArea()) // "nil"
|
||||
if let circle = myEmptyCircle {
|
||||
// will not execute since myEmptyCircle is nil
|
||||
print("circle is not nil")
|
||||
}
|
||||
|
||||
|
||||
@@ -432,7 +477,29 @@ enum BookName: String {
|
||||
case John = "John"
|
||||
case Luke = "Luke"
|
||||
}
|
||||
println("Name: \(BookName.John.rawValue)")
|
||||
print("Name: \(BookName.John.rawValue)")
|
||||
|
||||
// Enum with associated Values
|
||||
enum Furniture {
|
||||
// Associate with Int
|
||||
case Desk(height: Int)
|
||||
// Associate with String and Int
|
||||
case Chair(String, Int)
|
||||
|
||||
func description() -> String {
|
||||
switch self {
|
||||
case .Desk(let height):
|
||||
return "Desk with \(height) cm"
|
||||
case .Chair(let brand, let height):
|
||||
return "Chair of \(brand) with \(height) cm"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var desk: Furniture = .Desk(height: 80)
|
||||
print(desk.description()) // "Desk with 80 cm"
|
||||
var chair = Furniture.Chair("Foo", 40)
|
||||
print(chair.description()) // "Chair of Foo with 40 cm"
|
||||
|
||||
|
||||
//
|
||||
@@ -457,10 +524,13 @@ protocol ShapeGenerator {
|
||||
|
||||
class MyShape: Rect {
|
||||
var delegate: TransformShape?
|
||||
|
||||
|
||||
func grow() {
|
||||
sideLength += 2
|
||||
|
||||
|
||||
// Place a question mark after an optional property, method, or
|
||||
// subscript to gracefully ignore a nil value and return nil
|
||||
// instead of throwing a runtime error ("optional chaining").
|
||||
if let allow = self.delegate?.canReshape?() {
|
||||
// test for delegate then for method
|
||||
self.delegate?.reshaped?()
|
||||
@@ -482,21 +552,21 @@ extension Square: Printable {
|
||||
}
|
||||
}
|
||||
|
||||
println("Square: \(mySquare)")
|
||||
print("Square: \(mySquare)")
|
||||
|
||||
// You can also extend built-in types
|
||||
extension Int {
|
||||
var customProperty: String {
|
||||
return "This is \(self)"
|
||||
}
|
||||
|
||||
|
||||
func multiplyBy(num: Int) -> Int {
|
||||
return num * self
|
||||
}
|
||||
}
|
||||
|
||||
println(7.customProperty) // "This is 7"
|
||||
println(14.multiplyBy(2)) // 42
|
||||
print(7.customProperty) // "This is 7"
|
||||
print(14.multiplyBy(3)) // 42
|
||||
|
||||
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
|
||||
// requirements of the generics.
|
||||
@@ -510,7 +580,7 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
|
||||
return nil
|
||||
}
|
||||
let foundAtIndex = findIndex([1, 2, 3, 4], 3)
|
||||
println(foundAtIndex == 2) // true
|
||||
print(foundAtIndex == 2) // true
|
||||
|
||||
// Operators:
|
||||
// Custom operators can start with the characters:
|
||||
@@ -526,9 +596,23 @@ prefix func !!! (inout shape: Square) -> Square {
|
||||
}
|
||||
|
||||
// current value
|
||||
println(mySquare.sideLength) // 4
|
||||
print(mySquare.sideLength) // 4
|
||||
|
||||
// change side length using custom !!! operator, increases size by 3
|
||||
!!!mySquare
|
||||
println(mySquare.sideLength) // 12
|
||||
print(mySquare.sideLength) // 12
|
||||
|
||||
// Operators can also be generics
|
||||
infix operator <-> {}
|
||||
func <-><T: Equatable> (inout a: T, inout b: T) {
|
||||
let c = a
|
||||
a = b
|
||||
b = c
|
||||
}
|
||||
|
||||
var foo: Float = 10
|
||||
var bar: Float = 20
|
||||
|
||||
foo <-> bar
|
||||
print("foo is \(foo), bar is \(bar)") // "foo is 20.0, bar is 10.0"
|
||||
```
|
||||
|
Reference in New Issue
Block a user