Part 1: Welcome to Swift

《The Swift Programming Language》学习备忘录


章节前的数字索引依据原书定,并不是每个章节都做备忘的,所以索引会有所跳跃,原文没有索引,是我自己加上去的


先看看目录,内容就这么多,会把它看完,不会把它看完?这真是个问题



学习文档时用的是xcode6.1里面的帮助,现已发现新版本xcode6.3带得版本有些许不一样,若发现有啥不对的请以最新版本帮助为准。


Part 1: Welcome to Swift


1.2.2Control Flow

In an if statement, the conditional must be a Boolean expression—this means that code such asif score { ... } is an error, not an implicit comparison to zero.

You can use if and let together to work with values that might be missing. These values are represented as optionals. An optional value either contains a value or containsnil to indicate that the value is missing. Write a question mark (?) after the type of a value to mark the value as optional.


var optionalName:String? ="John Appleseed"

if let name =optionalName //let也可以是var后面可以修改var的值

    

}


//是不是这样理解:

//if的两种用法,1种后面接布尔表达式,另一种与let配合使用



Switches support any kind of data and a wide variety of comparison operations—they aren’t limited to integers and tests for equality.


  • letvegetable ="red pepper"
  • switchvegetable {
  • case"celery":
  •    letvegetableComment ="Add some raisins and make ants on a log."
  • case"cucumber","watercress":
  •    letvegetableComment ="That would make a good tea sandwich."
  • caseletxwherex.hasSuffix("pepper"):
  •    letvegetableComment = "Is it a spicy\(x)?"
  • default:
  •    letvegetableComment ="Everything tastes good in soup."
  • }


switch 支持任何类型


var firstForLoop =0

for iin0..<4 {

    firstForLoop += i

}

  • 可以用a..<b来制定一个区域,firstForLoop最终等于6

var firstForLoop =0

for iin0...4 {

    firstForLoop += i

}

可以用a...b 来制定一个区域,firstForLoop最终等于10


1.2.3Functions and Closures

  • func calculateStatistics(scores: [Int]) -> (min:Int, max: Int, sum:Int) {
  • }
  • 函数的返回值终于可以是多个值了,额。。。该说是一个呢,还是多个呢,还是一个带多个值的值呢?
  • func sumOf(numbers:Int...) ->Int {
  •     var sum = 0
  •     for number in numbers {
  •         sum += number
  •     }
  •     return sum
  • }
  • sumOf()
  • sumOf(42,597,12)

参数个数可以是不确定的


func returnFifteen() ->Int {

   var y =10

   func add() {

        y +=5

    }

   add()

   return y

}

returnFifteen()

函数可以内嵌



func makeIncrementer() -> (Int ->Int) {

   func addOne(number:Int) -> Int {

       return1 + number

    }

    return addOne

}

var increment =makeIncrementer()

increment(7)

返回一个函数的函数


func hasAnyMatches(list: [Int], condition:Int ->Bool) ->Bool {

   for itemin list {

       if condition(item) {

           returntrue

        }

    }

    return false

}

func lessThanTen(number:Int) ->Bool {

   return number <10

}

var numbers = [20,19,7, 12]

hasAnyMatches(numbers,lessThanTen)

函数作为参数




Functions are actually a special case of closures: blocks of code that can be called later. The code in a closure has access to things like variables and functions that were available in the scope where the closure was created, even if the closure is in a different scope when it is executed—you saw an example of this already with nested functions. You can write a closure without a name by surrounding code with braces ({}). Usein to separate the arguments and return type from the body.


var numbers = [20,19,7, 12]

numbers.map({

    (number:Int) ->Intin

   let result =3 * number

   return result

})


函数实际上就是闭包,一块将来被执行的代码,虽然代码在别处执行,但他能访问创建时上下文的变量,函数等。内嵌函数也说明了这一点。

可以写匿名闭包。

使用in将(参数和返回值)与闭包体隔开


You have several options for writing closures more concisely. When a closure’s type is already known, such as the callback for a delegate, you can omit the type of its parameters, its return type, or both. Single statement closures implicitly return the value of their only statement.


let mappedNumbers =numbers.map({ numberin3 * number })


更简洁的方式,如果闭包类型已知,比如代理的回调,你就可以直接使用其参数和返回类型


You can refer to parameters by number instead of by name—this approach is especially useful in very short closures. A closure passed as the last argument to a function can appear immediately after the parentheses.


let sortedNumbers =sorted(numbers) { $0 > $1 }

sortedNumbers


也可以连参数名都不用


1.2.4Objects and Classes


class NamedShape {

   var numberOfSides:Int = 0

   var name:String

   var name2:String?

    

   init(name:String) {

       self.name = name

    }

    

}

成员变量,如果不是可选的,则要在init中初始化,如果是可选则可不初始化


class EquilateralTriangle:NamedShape {

   var sideLength:Double =0.0

    

   init(sideLength:Double, name:String) {

       self.sideLength = sideLength

       super.init(name: name)

        numberOfSides =3

    }

    

   var perimeter:Double {

       get {

           return3.0 *sideLength

        }

       set {

           sideLength = newValue /3.0

        }

    }

    

   overridefunc simpleDescription() ->String {

        return"An equilateral triangle with sides of length\(sideLength)."

    }

}


初始化三步骤

1)初始化派生类声明的变量

2)调用父类的初始化函数

3)修改父类声明的变量。其他工作


If you don’t need to compute the property but still need to provide code that is run before and after setting a new value, usewillSet anddidSet. For example, the class below ensures that the side length of its triangle is always the same as the side length of its square.


class TriangleAndSquare {

    var triangle:EquilateralTriangle {

       willSet {

            square.sideLength = newValue.sideLength

        }

    }

   var square:Square {

       willSet {

            triangle.sideLength = newValue.sideLength

        }

    }

   init(size:Double, name:String) {

        square = Square(sideLength: size, name: name)

       triangle =EquilateralTriangle(sideLength: size, name: name)

    }

}


willSet,didSet不能和set一起用


Methods on classes have one important difference from functions. Parameter names in functions are used only within the function, but parameters names in methods are also used when you call the method (except for the first parameter). By default, a method has the same name for its parameters when you call it and within the method itself. You can specify a second name, which is used inside the method.


类方法与函数的一个重要的不同点,类方法的参数名也是标签(第一个参数除外),函数的参数名不能作为标签


1.2.5Enumerations and Structures

enum Rank:Int {

   case Ace =1

   case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten

   case Jack, Queen, King

   func simpleDescription() ->String {

       switchself {

       case .Ace:

           return"ace"

       case .Jack:

           return"jack"

       case .Queen:

           return"queen"

       case .King:

           return"king"

       default:

           returnString(self.rawValue)

        }

    }

}

let ace =Rank.Ace

let aceRawValue = ace.rawValue //aceRawValue  Int类型值为1


iflet convertedRank =Rank(rawValue: 3) {  //也可以用这种形式初始化

   let threeDescription = convertedRank.simpleDescription() //3

}


raw-value typeInt,所以只需指定第一个raw value,其他的将自动赋值


The member values of an enumeration are actual values, not just another way of writing their raw values. In fact, in cases where there isn’t a meaningful raw value, you don’t have to provide one.

enum Suit {

   case Spades, Hearts, Diamonds, Clubs

   func simpleDescription() ->String {

       switchself {

       case .Spades:

           return"spades"

       case .Hearts:

           return"hearts"

       case .Diamonds:

           return"diamonds"

       case .Clubs:

           return"clubs"

        }

    }

}

let hearts =Suit.Hearts

let heartsDescription =hearts.simpleDescription()

枚举不是另一种类型值的别名形式,实际上你可以不指定raw-value type


//You can also use strings or floating-point numbers as the raw type of an enumeration

//raw type可以是float, string, 但也不是什么类型都可以

enum rank2:Float{

   case r1 =1

   case r2,r3

}

let r1 =rank2.r1

r1.rawValue


enum rank3:String{

   case r31 ="31"

   case r32 ="32"

   case r33 ="33"

}

let r31 =rank3.r31

r31.rawValue


class rankClass {

   var m1:Int

   init(m1:Int){

       self.m1 = m1

    }

}


enum rank4: rankClass{//Raw type 'rankClass is not convertible from any literal'

   case r41 = rankClass(1)

    

}


Use struct to create a structure. Structures support many of the same behaviors as classes, including methods and initializers. One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference.

结构体与类的最主要区别,结构体在传递的时候总是拷贝副本,类则是传递引用



//一个枚举实例可以有多个值

enum ServerResponse {

   case Result(String, String)

   case Error(String)

}


let success = ServerResponse.Result("6:00 am","8:09 pm")

let failure = ServerResponse.Error("Out of cheese.")


switch success {

caselet .Result(sunrise, sunset)://把值取出来

   let serverResponse ="Sunrise is at \(sunrise) and sunset is at\(sunset)."

caselet .Error(error):

   let serverResponse ="Failure...  \(error)"

}


1.2.6Protocols and Extensions


//Classes, enumerations, and structs can all adopt protocols.

//类,枚举,结构体都可实现协议


protocol ExampleProtocol {

   var simpleDescription:String { get }

   mutatingfunc adjust()

}


class SimpleClass:ExampleProtocol {

   var simpleDescription:String = "A very simple class."

   var anotherProperty:Int = 69105

   func adjust() {

        simpleDescription +="  Now 100% adjusted."

    }

}

var a = SimpleClass()

a.adjust()

let aDescription =a.simpleDescription


struct SimpleStructure:ExampleProtocol {

   var simpleDescription:String = "A simple structure"

   mutatingfunc adjust() {

        simpleDescription +=" (adjusted)"

    }

}

var b = SimpleStructure()

b.adjust()

let bDescription =b.simpleDescription


SimpleStruturemutating关键字,标明这个方法会修改这个structure自身的值。

类则不需要,因为它默认就是可修改的


extension Int:ExampleProtocol {

   var simpleDescription:String {

        return"The number\(self)"

    }

   mutatingfunc adjust() {

       self +=42

    }

}

7.simpleDescription


使用extension给已存在类增加功能,比如新方法和计算属性。也可以实现某个协议,如上



1.2.7Generics

Write a name inside angle brackets to make a generic function or type.


func repeat<Item>(item:Item, times:Int) -> [Item] {

   var result = [Item]()

   for iin 0..<times {

        result.append(item)

    }

   return result

}

repeat("knock",4)


You can make generic forms of functions and methods, as well as classes, enumerations, and structures.

//函数,方法,类,枚举,结构体都可以使用模板


//看看可选模板

// Reimplement the Swift standard library's optional type

enum OptionalValue<T> {

   case None

   case Some(T)

}

var possibleInteger:OptionalValue<Int> = .None

possibleInteger = .Some(100)


//使用where标明类型要求

func anyCommonElements <T, Uwhere T: SequenceType, U: SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs:T, rhs: U) ->Bool {

   for lhsItemin lhs {

       for rhsItemin rhs {

           if lhsItem == rhsItem {

               returntrue

            }

        }

    }

    return false

}

anyCommonElements([1,2,3], [3])


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值