swift x输入流_swift 学习(一)基础知识 (基本数据类型,操作符,流控制,集合)...

邢俊悟
2023-12-01

xcode 中调用API帮助

1、查看简单信息,选中后 按键 control +左键单击  或者按 右侧属性栏 里的帮助按钮

2、完整API,选中后 按键control +左键双击

3、查看类、函数等的注释,参数列表等,alt +左键单击

4、代码块注释与取消注释的快捷键 都是 command + /

5、---不能用try...catch,但可用assertion 调试,有多个重载版本,assert(useDate<=0,"不符合则报错")

swift2.0中已引入do-catch语句

正文

初步印象

1. 字符统一用unicode编码,区分大小写,有很多类似js,java的用法

2. 类型安全:有可选类型,可选类型的值缺失时为 nil ,不再需要对一个值判别是否为Null,变量声明时已经确定

3. 在swift中,数字字面量之间的运算,支持隐式类型转换,但数字类型的变量和常量之间的运算,则不再支持隐式类型转换。

4. 标示符命名规则与C相同,但是 关键字可以做标示符

let π = 3.14  等价于 let  `π` = 3.14

var `class`="sdd"

5. 字符串比对时加入了更多判断。不再只是简单地比对组成字符串的标量,而是会比对最终表现形式

6. 字符和字符串都用双引号

7. 句末不用写分号,但多条语句写在同一行时要加

8. 变量声明用var, 常量用let,因此变量声明格式 变化较大  ,数据类型编译器会自动识别,一般不用显式声明

let a = 2

var b: Double = 4

var aInt = 4, bInt = 7

var p1 = 10,p2:Double

9. swift 语法内容很少,使用也很方便。而且函数是第一性的,也有全局变量,面向对象,面向过程,函数式都可以尝试。就是太多与objective-c相关的东西。

10. 声明字典,数组用 方括号,而不是花括号, 元组 用圆括号

11. 接口关键字改做protocal,更形象了

12. 枚举和结构的功能增强了,可以加入属性,方法,也可以实现接口

一段Swift代码(可选类型的源码)

enum Optional : Reflectable, NilLiteralConvertible {

case None

case Some(T)

/// Construct a `nil` instance.

init()

/// Construct a non-\ `nil` instance that stores `some`.

init(_ some: T)

/// If `self == nil`, returns `nil`. Otherwise, returns `f(self!)`.

func map(f: @noescape (T) -> U) -> U?

/// Returns `f(self)!` iff `self` and `f(self)` are not nil.

func flatMap(f: @noescape (T) -> U?) -> U?

/// Returns a mirror that reflects `self`.

func getMirror() -> MirrorType

/// Create an instance initialized with `nil`.

init(nilLiteral: ())

}

extension Optional : DebugPrintable {

/// A textual representation of `self`, suitable for debugging.

var debugDescription: String { get }

}

注意点

1、 xcode 中 swift 运算符 两边要加空格,否则多数时候会报错(赋值 和 比较)

关键字 共60个

与声明有关的14个:class, deinit, enum, extension, func, import, init, let, protocol, static, struct, subscript, typealias, var

与语句有关的14个:break, case, continue, default, do, else, fallthrough, if, in, for, return, switch, where, while

表达式和类型关键字12个:as, dynamicType, is, new, super, self, Self, Type, _COLUMU_ , _FILE_ , _FUNCTION_ , _LINE_

特定上下文中使用的20个:associativity, didset, get, infix, inout, left, mutating, none, nonmutating, operator, override, postfix, precedence, prefix, rightset, unowned, unowned(safe), unowned(unsafe), weak, willset

补充:finaly private public internal dynamic

@IBoutlet @IBAction  @UIApplicationMain @objc

@autoclosure @autoclosure(escaping)

@autoclosure:用在函数的里标记一个参数,然后这个参数会先被隐式的包装为一个closure,再把closure作为参数给这个函数。 从而实现对传递给这个参数的表达式延迟求值。

func myassert(@auto_closure predicate : () -> Bool) {

#if !NDEBUG

if predicate() {

abort()

}

#endif

}

//调用

myassert(someExpensiveComputation() != 42)

func &&(lhs: LogicValue, @auto_closure rhs: () -> LogicValue) -> Bool {

return lhs.getLogicValue() ? rhs().getLogicValue() : false

}

1.2 新增:@noescape:可以用在函数的闭包参数上,这意味着这个参数是唯一可被调用的(或者用在函数调用时以参数的方式出现),其意思是它的生命周期比函数调用的周期短,这有助于一些小小的性能优化,但最重要的是它屏蔽了闭包中对self.的需求。这使得函数的控制流比其他更加透明。在未来的beta版本中,标准库函数将普遍采用这种特性,比如autoreleasepool():

func autoreleasepool(@noescape code: () -> ()) {

pushAutoreleasePool()

code()

popAutoreleasePool()

}

使用在函数参数上的 @autoclosure属性现在含有@noescape新属性的功能,这个改进限制了@autoclosure作为控制流程以及惰性计算的能力。

第二种形式。@autoclosure(escaping), 和@autoclosure有着同样的调用形式,但是它允许产生结果的闭包在实现中缓存

运算符

优先级排序:

最高:  ++, --, !, ~, - , +

160:   << , >>

150:   * , / , % , & , &* , &/ , &%

140:   + , - , &+ , &- , | , ^

135:   ..< , ...

132:   is , as

130:   < , <= , > , >= , == , != , === , !==

120:   &&

110:   ||,??

100:   ?:

90:   =, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^=, &&=, ||=

swift特点

swift 赋值运算符并不能将自身作为一个值进行返回

if x = y {} // 报错

println(a = 3) // ()

swift 默认情况下算数运算符不容许值溢出,需使用溢出运算符

&+,&*: 溢出加法 用于整数 上溢出

var max = UInt16.max // 65535

println(max + 1)         // 报错

println(max &+ 1)       // 0

var max = Int16.max  // 32767

println(max &+ 1)      // -32768

&-,&*: 整数下溢出

&/, &%  解决除数为0 的情况,xcode不识别了,已经被移除

swift中可以浮点数求余

let a = 3.667 % 1.3   // 1.067

swift 中提供了 恒等运算符===,!==,用来测试两个对象的引用是否来自同一个对象实例

可选类型与拆封运算

// nil不同于c中的NULL,它表示值缺失,而不是空指针

// 只有可选类型的变量或常量才可接受nil,非可选类型的变量或常量不能接受nil

func divide(a:Double,b:Double) ->Double? {

if(b == 0){

return nil

}

return a / b

}

let result1 : Double? = divide(100,1)

println(result1) // Optional(100.0)

//强制拆封 (确定可选类型一定有值,可在读取它时通过拆封获取这个值)

if result1 != nil{

println(result1!) //100

result1?.hashValue

}

//隐式拆封(更方便访问,会自动解封,若此时数据为nil,则后续操作可能出错)

let result2 : Double! = divide (100,0)

println(result2) //nil

// result2.hashValue // 报错

result2?.hashValue // nil,添加问号则如果result2为nil就不会执行后续

let result3 : Double! = divide (100,2)

println(result3) //50.0

result3.hashValue

?? 空值合并运算符

// 对 a 进行判断,如果不为 nil 则解包,否则就返回 b

// a 必须是 optional 的

// b 必须和 a 类型一致

// 相当于三目运算符的简化版

var a: String? = "a"

var b: String? = "b"

var c = a ?? b // "a"

a = nil

c = a ?? b // "b"

b = nil

c = a ?? b ?? "c" // "c"

//简化代码

if allowEmpty || items?.count ?? 0 > 0 {

}

区间运算符分为闭区间 (...) 和左闭右开区间 (..

//1...100 等同于 1..<101,区间

// 区间运算符其实返回的是一个 Range 对象,是一个连续无关联序列索引的集合。

// .....

let aNumber:Int = 3

switch aNumber

{

case 0...5:

println("This number is between 0 and 5")

case 6...10:

println("This number is between 6 and 10")

default:

println("This number is not between 0 and 10")

}

// .....

(1...10).map{

"$\($0)" + ".00"

}

// .generate() 遍历 Range 中的值。

var range = 1...4

var generator = range.generate() // {startIndex 1, endIndex 5}

var item:Int?

do{

item = generator.next()

println(item)

}while(item != nil)

//区间运算符返回的是一个 ClosedInterval 或者 HalfOpenInterval 的东西,

//类型只要是 Comparable 就可以了。所以我们也可以把 String 放到 ... 里。

let interval3 = 4.6...7.8

interval3.contains(4.88) // true

//通过 String 的 ClosedInterval 来输出字符串中的小写字母:

let test = "Hello"

let interval = "a"..."z"

// 交集

let interval2 = interval.clamp("d"..."h")

for c in test.characters {

if interval.contains(String(c)) {

println("\(c)")

}

} //e l l o

+Inf, -Inf, NAN

//let a = 23 / 0 // 报错,0不能做除数

let b = 23.0 / 0 // inf 正无穷大

let bb = 23.0 / -0 // inf 正无穷大

let c = -23.0 / 0 // -inf 负无穷大

let cc = -23.0 / -0 // -inf 负无穷大

let d = 0.0 / 0 // nan 非数

let dd = 0.0 / -0 // nan 非数

b == bb // true

c == cc // true

d == dd // false

运算符重载

1. 非常实用,但也相当有风险,可读性问题,可使用字符为:/ = – + * % < > ! & | ^ . ~

2. 运算符函数即便写在类内部,定义后也会自动进入全局Global作用域,而不是作为类的一个成员函数

struct Vector2D {

var x = 1.0, y = 1.0

}

// 实现结构类型Vector2D的加法

func + (left: Vector2D, right: Vector2D) -> Vector2D {

return Vector2D(x: left.x + right.x, y: left.y + right.y)

}

func *(vector2D: Vector2D,scalar:Double)->Vector2D{

return Vector2D(x: vector2D.x * scalar, y: vector2D.y * scalar)

}

// 1.实现 组合赋值运算符 左参数要设置为inout,赋值运算没有返回值

func += (inout left: Vector2D, right: Vector2D){

left = left + right

}

// 3. 会把1,2都覆盖了,不会报错

func += (left: Vector2D, right: Vector2D)->Vector2D{

let left2 = left + right

return left2

}

// 2.也可以有返回值,与1 不能并存

func += (inout left: Vector2D, right: Vector2D)->Vector2D{

left = left + right

return left

}

// 实现一个单目运算符,需要加前缀prefix或 postfix

//

prefix func -(vector2D:Vector2D)->Vector2D{

return Vector2D(x: -vector2D.x, y: -vector2D.y)

}

// 1.运算结果要保存,则要用inout

prefix func ++(inout vector2D:Vector2D)->Vector2D{

vector2D = vector2D + Vector2D(x: 1,y: 1)

return vector2D

}

// 3.会覆盖1,2 。不保存运算结果,有返回值

prefix func ++(vector2D:Vector2D)->Vector2D{

let vector2D2 = vector2D + Vector2D(x: 1,y: 1)

return vector2D2

}

// 2. 没有返回值

prefix func ++(inout vector2D:Vector2D){

vector2D = vector2D + Vector2D(x: 1,y: 1)

}

postfix func ++(inout vector2D:Vector2D)->Vector2D{

let _vector2D = vector2D

vector2D = vector2D + Vector2D(x: 1,y: 1)

return _vector2D

}

// 非是对原有操作符的新应用,则要先声明其为操作符

prefix operator +++ {}

prefix func +++(var c: Vector2D) -> Vector2D{

c += c

c += Vector2D(x: 1.0, y: 1.0)

return c

}

/// 自定义运算符需要遵循两段式,即需要先声明运算符

/// infix / prefix / postfix

/// associativity 表示结合性:left,rigth,none,默认为none

/// 指的事和其他运算符优先级相同的情况下,是从左边开始计算还是右边

/// precedence 表示优先级的数值,0...255,默认100

/// assignment 定义组合运算符时需要用到这个,

infix operator +-{ associativity left precedence 140}

func +-(left:Vector2D,right:Vector2D)->Vector2D{

return Vector2D(x:left.x + right.x,y:left.y - right.y)

}

infix operator +-={associativity right precedence 140 assignment}

func +-=(inout left:Vector2D,right:Vector2D)->Vector2D{

left = Vector2D(x:left.x + right.x,y:left.y - right.y)

return left

}

var point = Vector2D(x: 3.0, y: 1.0)

var v1 = Vector2D(x: 1,y: 1)

++v1 //{x 2, y 2}

v1 //{x 2, y 2}

v1++ //{x 2, y 2}

v1 //{x 3, y 3}

-v1 //{x -3, y -3}

+++point //{x 7.0, y 3.0}

point //{x 3, y 1}

v1+-point //{x 6, y 2}

v1+-=point //{x 6, y 2}

v1 //{x 6, y 2}

let v3 = v1 += point

v3

v1

数据类型

swift中,不同于c,java等的基本数据类型那样单纯表示数值,

swift中 基本数据类型和集合全部由结构或枚举实现,虽然牺牲了性能,但是功能却强大了很多。

基本数据类型

整型(Int8,Int16,Int32,Int64,Int(32位平台与Int32等宽,64位平台与Int64等宽),UInt8,UInt16,UInt32,UInt64,UInt)

浮点型(Float, Double)float 32位,double64位,默认浮点数为double

字符 let a:Character = "&"  let b ="\u{1fb03}"   字符也用双引号

字符串  字符串拼接 let number = 9 ; let total = "\(number)加10等于\(Double(number) + 10)"

布尔型 Bool 只有两个值true,false,不能用0,1代替

元组(tuple)类型(记录)

var student1 =("1001","张飞",20,96) 或 var student2 = (id:"1001",name:"张飞",age:20,score:96)

或 var  student3 : (String,String,Int,Int) ; student3 = ("1001","张飞",20,96)

访问元组字段: student1.0, student2.0,student2.id

枚举

结构

typealias MyInt = Int

var x :MyInt = 10

swift 中除类以外,所有基本数据类型,集合都是由结构实现,所有都可以调用构造器来初始化

let x = Float() //0.0

let y = Double() //0.0

let z = Int() //0

let aa = Bool()//false

let bb = Character("S") //Character没有无参初始化

let dd = String() //""

let ee = [Int]()//0 elements

let ff = [Int:String]()//0 key/value pairs

let gg = Set() //0 members

let xxx: () = ()

swift里除了类以外的基本类型都是由结构体实现的,也既是除了类以外都是值引用类型

不再支持数字类型的隐式转换

let pi = 3 + 0.1415926 // pi的类型推导为double(最大精度匹配原则)

let anInt = 10

let aDouble = 3.14

//var result = anInt + aDouble //报错

var result = Double(anInt) + aDouble

let aChar:Character = "a"

//var a:Character = anInt + aChar //报错

//var b:Int = a //报错

Int8.min,Int8.max

二进制:0b,八进制:0o,十六进制:0x,指数:1.56e-2; 十六进制指数 0x5.a2p2(0x5.a2 * 22)

swift 为方便阅读,整形,浮点均可添加多个零或下划线以提高可读性 var a = 000.0145 ; var b = 3_360_000

// 整形

let a = 100

a.byteSwapped

a.bigEndian

a.littleEndian

a.toIntMax()

a.value

a.advancedBy(100)

a.description

字符Character,字符串String 都使用""

String 本质上是一个Struct,因此可以用构造器来创建字符串

var str1 = "2sfer"

var str2 = String()

var str3 = String(count:5,repeatedValue:Character("f"))

let character:Character = "a"

let str4 = String(character)

let characters:[Character] = ["c","b","a"]

let str5 = String(characters)

字符串日常操作:是否包含某字符,rangOfString,前后缀,大小写切换,分割等

let someone = "Joris Kluivers"

let end2 = someone.rangeOfString(" ")//5..<6

if (end2 != nil) {

let firstName = someone[someone.startIndex..

} else {

// no space found

}

// 前后缀

let doc = "Java.docx"

if doc.hasSuffix(".docx"){}

if doc.lowercaseString.hasPrefix("java"){}

// 大小写

"Hello, playground".uppercaseString //HELLO, PLAYGROUND

"Hello, playground".lowercaseString //hello, playground

// 分割

"Hello, playground".componentsSeparatedByCharactersInSet(

NSCharacterSet(charactersInString: "eo")

) //["H", "ll", ", playgr", "und"]

"Hello, playground".componentsSeparatedByString("play")//["Hello, ", "ground"]

var cafe = "cafe"

// 插入字符

cafe.insert("!", atIndex: cafe.endIndex) // "cafe!"

// 插入字符串

cafe.insertContentsOf(" is delicious".characters , at: cafe.endIndex.predecessor())//"cafe is delicious!"

//移除字符

cafe.removeAtIndex(cafe.endIndex.predecessor()) // "!"

//移除字符

cafe.removeRange(cafe.startIndex.advancedBy(1)...cafe.startIndex.advancedBy(3))// "c is delicious"

//替换 ,移除字符单位置还在

cafe.replaceRange(cafe.startIndex.advancedBy(1)...cafe.startIndex.advancedBy(3), with: "afe") //"cafe delicious"

swift中每一个字符都代表了一个可扩展字母集(Extended Grapheme Clusters)

每一个可扩展的字母集,又由一个或几个有序的Unicode标量的值(Unicode scalar value)所组成,以上这些构成了人类可读的字符。

//形同c中用ascii编码,swift用unicode编码,

一个unicode标量占21个bit,

取值范围,U+0000到U+D7FF和从 U+E000 到U+10FFFF,不包括 U+D800 到 U+DFFF

let dollarSign = "\u{24}"

let blackHeart = "\u{2665}"

String 用结构实现,是值类型,而NSString 用类实现,是引用类型

String.Characters.count,和 NSString.length 并不总是完全一样的值,因为前者统计的是有意义的Extended Grapheme Clusters 个数,后者是UTF-16编码 计数

var word = "cafe"

word.characters.count // 4

(word as NSString).length // 4

word += "\u{301}" // "café", 组合了一个重音符号

word.characters.count // 4

(word as NSString).length // 5

word += "\u{301}" // "café́", 再组合了一个重音符号

word.characters.count // 4

(word as NSString).length // 6

word += "\u{301}" // "café́́", 再组合了一个重音符号

word.characters.count // 4

(word as NSString).length // 7

word += "\u{301}" // "café́́́", 再组合了一个重音符号

word.characters.count // 4

(word as NSString).length // 8

word += "\u{301}" // "café́́́́", 再组合了一个重音符号

word.characters.count // 4

(word as NSString).length // 9

word += "\u{20dd}" // "café́́́́⃝", 再组合了一个圆

word.characters.count // 4

(word as NSString).length // 10

var decomposed:Character = "\u{1112}\u{1161}\u{11ab}" // "한" 由三个Unicode标量组成,但是一个字符

var decomposedString:String = "\u{1112}\u{1161}\u{11ab}"

// 用 for in 遍历字符串

for c in decomposedString.characters{

print(c) // "한", 只有一个字符

}

//用下标遍历

let end = decomposedString.endIndex // 3 最后一个Unicode标量的位置+1

var i = decomposedString.startIndex // 0

i.advancedBy(1) // 3

for(var j = decomposedString.startIndex;j

print(decomposedString[j])

}

let NSdecomposedString = decomposedString as NSString

for var i = 0; i < NSdecomposedString.length; i++ {

//3 times (4370, 4449, 4523)

print(NSdecomposedString.characterAtIndex(i))

}

let u1 = UnicodeScalar(4370) // 4370

let u2 = UnicodeScalar(4449) // 4449

let u3 = UnicodeScalar(4523) // 4523

let c1 = Character(u1) // ᄒ

let c2 = Character(u2) // ᅡ

let c3 = Character(u3) // ᆫ

let c = Character("\(c1)\(c2)\(c3)") // 한

swift中字符串的比较会 比对每个字符的语义和最终表现形式。而不是比对构成字符的标量

let word1 = "caf\u{e9}" // "café" \u{e9} 带音调的拉丁字母e

let word2 = "caf\u{65}\u{301}" // "café" \u{65}\u{301} 拉丁字母e + 一个重音符号

word1 == word2 // true

// 转化为 NSString 后比对

(word1 as NSString) == (word2 as NSString) // false

let a1 = "\u{41}" // 拉丁字母 A

let a2 = "\u{0410}" // 斯拉夫字母 A

a1 == a2 // false

子字符串:无法用Int下标来访问String中的字符或字串,而使用String.Index

var imageStr = ""

let start = imageStr.startIndex.advancedBy(2) //4

let end = imageStr.startIndex.advancedBy(3) //6

let range = start..

print(range.debugDescription) // Range(4..<6)

print(imageStr[range]) //

print(imageStr.substringFromIndex(start))//

print(imageStr.rangeOfString(""))// Optional(Range(4..<6))

print(imageStr.substringToIndex(start))//""

(imageStr as NSString).substringFromIndex(1)//�"

var imageStr = "s"

//下标:swift中数组,字符串都支持 区间做下标

extension String {

subscript (r: Range) -> String {

get {

let startIndex = self.startIndex.advancedBy(r.startIndex)

let endIndex = startIndex.advancedBy(r.endIndex - r.startIndex)

return self[Range(start: startIndex, end: endIndex)]

}

}

}

var s = "Hello, playground"

print(s[0...5]) // ==> "Hello,"

print(s[0..<5]) // ==> "Hello"

imageStr[1..<2] //

编码

let S1:String = "one "

//swift 1.2时 ᄒ ᅡ ᆫ三个标量还是三个字符,2.1自动替换为한

let a = "ᄒ"

let b = "ᅡ"

let c = "ᆫ"

let S2:String = "\(a)\(b)\(c)"//"한"

let view1:String.UnicodeScalarView = S1.unicodeScalars //one 

let view2:String.UTF16View = S1.utf16 //one 

let view3:String.UTF8View = S1.utf8 //one 

view3.debugDescription //UTF8View("one ")

// utf-8编码

for i in S1.utf8 {//遍历utf-8编码的字符串

// 前4个ascii字符各占一个字节 111 110 101 32

// 中间两个emoji表情240 159 144 177, 240 159 144 173

// 最后一个emoji表情240 159 135 168, 240 159 135 179

print(i) // 20 times

}

for i in S2.utf8 {//遍历utf-8编码的字符串

// ᄒ 225 132 146

// ᅡ 225 133 161

// ᆫ 225 134 171

print(i)

}

// utf-16编码

for i in S1.utf16 {//遍历utf-16编码的字符串

// 前4个ascii字符各占一个字节 111 110 101 32

// 中间两个emoji表情 55357 56369, 55357 56365

// 最后一个emoji表情 55356 56808, 55356 56819

print(i) // 12个数字 12 times

}

let NSS1 = S1 as NSString

for(var i=0;i

print(NSS1.characterAtIndex(i)) // 12个数字 12 times

}

for i in S2.utf16 {//遍历utf-16编码的字符串

//4370 4449 4523

print(i)

}

let NSS2 = S2 as NSString //한

for(var i=0;i

print(NSS2.characterAtIndex(i)) // 54620

}

// unicode标量

for i in S1.unicodeScalars {//遍历unicode标量

// 最后一个emoji表情由两个unicode标量组成

print(i) // one   8times

}

for i in S2.unicodeScalars {//遍历unicode标量

//ᄒ ᅡ ᆫ 3 times

print(i)

}

//遍历字符

for i in S1.characters {//遍历字符

print(i) // one  7 times

}

for i in S2.characters {//遍历字符

print(i) // 한 1 times

}

与c语言字符串的转换

// 以某种编码取到 c String

//[72, 101, 108, 108, 111, 44, 32, 112, 108, 97, 121, 103, 114, 111, 117, 110, 100, 0]

let xxxx = "Hello, playground".cStringUsingEncoding(NSASCIIStringEncoding)

// 从cString转回String

//"Hello, playground"

String.fromCString(xxxx!)

let anInt = 10

let aChar:Character = "a"

if var xx = "\(aChar)".cStringUsingEncoding(NSASCIIStringEncoding){

xx[0] = anInt + xx[0] // 107

let s:String = String.fromCString(xx)! // "k"

}

let yy = String.cStringUsingEncoding("") //UInt -> Optional>

let code1 = yy(NSUTF8StringEncoding)//[-16, -97, -112, -79, 0]

let code2 = yy(NSUTF16StringEncoding)//[61, -40, 49, -36, 0]

let code3 = yy(NSASCIIStringEncoding)//nil

String.fromCString(code1!) // "" ,c语言字符是ascii编码

String.fromCString(code2!) // nil

String.fromCString(code3!) //fatal error: unexpectedly found nil while unwrapping an Optional value

流程控制

流程控制语句中条件表达式的小括号 可以省略, 但 代码块的 大括号不能再省略

if let ,if var语句(可选绑定,如果可选类型的变量或常量有值,则会赋值给另一个临时变量或常量)

// 自动拆封,简化了判别代码

func foo()->Int?{

return 1

}

func bar()->Int?{

return 2

}

func baz(a:Int,b:Int)->String?{

return "ss"

}

if let a = foo(), b = bar() where a < b, let c = baz(a,b) {

println(c)

}

也可用if var 声明为变量

var aaa:Int? = 12

if var bb = aaa{

bb++

println(bb)

}

分支语句 switch有较大变化

3.1 swift中switch语句可以使用几乎所有数据类型,而C中只有整数,c#也仅支持基本数据类型。

3.2 c中的取值是离散的(case后为常量表达式),而Swift中可以离散 也可以是连续的范围区间 还可用 let where 进行过滤( if let 形式)

3.3 swift 中case 分支 无需添加 break 语句,分支执行完会跳出跳出switch,要连通多个case 需要用到 fallthrough 语句

但细分下来,swift中switch与c#是类似的,不同之处在于可以使用元组,区间,以及类似 if let  where 的结构,以及break的默认添加

//类似c中的离散整型

let testscore = 86

var grade:Character

switch testscore / 10 {

case 9: grade = "优"

case 8: grade = "良"

case 7,6: grade = "中"

default : grade = "差"

}

//浮点

let value = 1.000

var desc:String

switch value {

case 0.0: desc = "最小值"

case 0.5: desc = "中值"

case 1.0: desc = "最大值"

default : desc = "其他值"

}

//字符

let level= "优"

var desc:String

switch level {

case "优": desc = "90分以上"

case "良": desc = "80分~90分"

case "中": desc = "60~80分"

case "差": desc = "低于60分"

default : desc = "无法判断"

}

//区间

let testscore = 86

var grade:Character

switch testscore {

case 90...100 : grade = "优"

case 80..<90: grade = "良"

case 60..<80: grade = "中"

default : grade = "差"

}

//元组

var student = (id:"1002",name:"李四",age:32,ChineseScore:80,EnglishScore:79)

var grade:String

switch student {

case (_,_,_,90...100,90...100) : grade = "优"

case (_,_,_,80..<90,80..<90) : grade = "良"

case (_,_,_,60..<80,60..<80): grade = "中"

case (_,_,_,60..<80,90...100),(_,_,_,90...100,60..<80): grade = "偏科"

case (_,_,_,0..<80,90...100),(_,_,_,90...100,0..<80): grade = "严重偏科"

default : grade = "无"

}

//元组 值绑定

var student = (id:"1002",name:"李四",age:32,ChineseScore:80,EnglishScore:79)

var grade:String

switch student {

case (_,_, let age,90...100,90...100) :

if (age > 30) { grade = "老优" } //大括号省略了会报错

else { grade = "小优" }

case (_,_,_,80..<90,80..<90) : grade = "良"

case (_,_,_,60..<80,60..<80): grade = "中"

case (_,_,_,60..<80,90...100),(_,_,_,90...100,60..<80): grade = "偏科"

case (_,_,_,0..<80,90...100),(_,_,_,90...100,0..<80): grade = "严重偏科"

default : grade = "无"

}

//元组 值绑定 情况下, 使用 where 语句进行条件过滤

var student = (id:"1002",name:"李四",age:32,ChineseScore:80,EnglishScore:79)

var grade:String

switch student {

case (_,_, let age,90...100,90...100) where age < 30 : grade = "小优"

case (_,_,_,90...100,90...100) : grade = "老优"

case (_,_,_,80..<90,80..<90) : grade = "良"

case (_,_,_,60..<80,60..<80): grade = "中"

case (_,_,_,60..<80,90...100),(_,_,_,90...100,60..<80): grade = "偏科"

case (_,_,_,0..<80,90...100),(_,_,_,90...100,0..<80): grade = "严重偏科"

default : grade = "无"

}

let yetAnotherPoint = (1, -1)

switch yetAnotherPoint {

case let (x, y) where x == y:

println("(\(x), \(y)) is on the line x == y")

case let (x, y) where x == -y:

println("(\(x), \(y)) is on the line x == -y")

case let (x, y):

println("(\(x), \(y)) is just some arbitrary point")

}

// "(1, -1) is on the line x == -y"

其他循环 while, for , for in ,与其他语言用法上几本没有变动,do while 2.0后改为repeat{}while(), 关键字do用于错误处理

跳转  return,break , continue, fallthrough,没有goto了

fallthrough是新增关键字,用于switch中

break , continue 也有变化

outFor: for a in 1...5{

for i in 1...10{

if i == 2{

//continue //45 times

continue outFor // 5 times

}

println("\(a):\(i)")

}

}

outFor: for a in 1...5{

for i in 1...10{

if i == 2{

// break // 5 times

break outFor // 1:1

}

println("\(a):\(i)")

}

}

break 在switch 中,每个case一旦匹配,都会有默认的break,想如同c 般跨越多个case,需要使用fallthrough,但如果case匹配后没有任何操作,则需要主动加一个 break

//类似c中的离散整型

let testscore = 86

var grade:Character

switch testscore / 10 {

case 9: break//grade = "优"

case 8: fallthrough//grade = "良"

case 7,6: grade = "中"

default : grade = "差"

}

集合

swift 中集合都是由结构实现的,所以都属于值引用,这和objective-c 是不一样的

数组 Array  关联 NSArray

var a: Array 等价于  var a: [Int]

var a: Array = [1,2]

var a = [Int]()

var threeDoubles = [Double](count:3,repeatedValue:0.0) //重复值的初始化

数组创建完成后,清空元素,a = []

//未指明数组中的数据类型,下列会自动推导为[AnyObject],等同于NSArray

var array = [0,"","ssf",4]

// 访问数组元素

print(array[0]) //"0"

print(array[1...2]) //["", "ssf"]

print(array.first) // 0

print(array.last) // 4

// 移除元素

let temp = array.removeAtIndex(0)

print(array) // [, ssf, 4]

print(temp) // "0"

// 清空元素

array = [] //0 elements

// 新元素

array.append(4) //[4]

array.appendContentsOf([22,44]) //[4, 22, 44]

array += ["df",4.5] //[4, 22, 44, "df", 4.5]

array.insert("3",atIndex:array.count) //[4, 22, 44, "df", 4.5, "3"]

array[1...1] = [4,5,6] //[4, 4, 5, 6, 44, df, 4.5, 3]

array[0...2] = [1] //[1, 6, 44, df, 4.5, 3]

array.insert(2, atIndex: 1) //[1, 2, 6, 44, "df", 4.5, "3"]

array.removeLast() //[1, 2, 6, 44, "df", 4.5]

array.removeFirst(3) //[44, "df", 4.5]

array.removeFirst() //["df", 4.5]

// 数组的值引用 测试

var array2 = array //[4, 4, 5, 6, 44, "df", 4.5, "3"]

array[0] = 1

print(array) //[1, 4, 5, 6, 44, df, 4.5, 3]"

print(array2) //[4, 4, 5, 6, 44, df, 4.5, 3]

//其他属性

array.capacity // 8

array.count // 8

array.description

array.debugDescription

array.endIndex // 8

array.isEmpty

// 迭代器

var gene = array.generate()

gene.next()

// 遍历

for x in array {

print(x)

}

for (index,value) in array.enumerate() {

print("item\(index + 1):\(value)")

}

for var i = 0; i < array.count; i++ {

print("item\(i + 1):\(array[i])")

}

// =======================

var array3 = [1,5,3]

// 拼接字符串

print(array3.map{"$\($0)" + ".00"}.joinWithSeparator(" - ")) //$1.00 - $5.00 - $3.00

拼接数组 2.0不能用了

//array3.join([[],[],[]]) //[1, 5, 3, 1, 5, 3]

//array3.join([[4,6,7],[1,2],[3,4,6]]) //[4, 6, 7, 1, 5, 3, 1, 2, 1, 5, 3, 3, 4, 6]

// 排序

// 得到一个新数组

array3.sort(

{$0 > $1}

)

// 默认升序

array3.sort()

// 对原数组修改

array3.sortInPlace(){

return $0 > $1

}

// 默认升序

array3.sortInPlace()

// 得到一个倒序数组

array3.reverse() //[5, 3, 1]

//map 数组按一定规则转为另一数组

//map函数会对每一条输入进行指定的操作,然后为每一条输入返回一个对象

//而flatMap函数则是两个操作的集合——正是“先映射后扁平化”:

//操作1:同map函数一样:对每一条输入进行指定的操作,然后为每一条输入返回一个对象

//操作2:最后将所有对象合并为一个对象

array3.flatMap{

[$0 + 4, $0 * 2]

}//[5, 2, 7, 6, 9, 10]

//filter 筛选

array3.filter{

$0 <= 3

}//[1,3]

//reduce将数组中的值整合到某个独立对象里,有两个参数一个原始值,一个闭包,闭包返回的结果也就是下一轮循环的原始值

// 闭包的两个参数,左侧为原始值,右侧为当前数组元素

array3.reduce(2,

combine: {$0 + $1}

) //11

array3.reduce(2, combine: +)//操作符本身就是一个函数 //11

集合 Set   关联 NSSet

// 集合set,无序,元素不能重复

// 集合中的元素要求都有hashvalue,swift 中所有基本数据类型都是可哈希的

var vowel:Set = ["a","e","i","o","u"]

var evenSet:Set = [2,4,5,6]

var set = Set()

set.insert(1)

set.insert(1)

set.insert(2) //{2, 1}

set.contains(2)

set.count

set.debugDescription

set.description

set.first

set.insert(3)

set.removeFirst()

for i in set{

print(i)

}

for i in set.sort(){

print(i)

}

// 集合运算

var setA:Set = [1,2,3,4,5,6]

var setB:Set = [4,5,6,7,8,9]

// 交集

let interSetAB = setA.intersect(setB) //{5, 6, 4}

let exclusiveSetAB = setA.exclusiveOr(setB) //{9, 7, 2, 3, 1, 8}

let unionSetAb = setA.union(setB) //{2, 4, 9, 5, 6, 7, 3, 1, 8}

let aSubstractB = setA.subtract(setB) //{2, 3, 1}

var setC:Set = [1,2,3]

if setA == setB{

}

setA.isSubsetOf(setC) //false

setA.isSupersetOf(setC) //true

setC.isDisjointWith(setB) //true

setA.isStrictSupersetOf(setC) //true

setC.isStrictSubsetOf(setA) //true

字典 Dictionary  关联 NSDictionary

var a: Dictionary = [101: "张飞", 102:"关羽"]

var b = Dictionary()

var c = [String : (NSCache, UIView)]()

var formats : [String : (NSCache, UIView)] = [:]

字典中所有能作为键的类型,必须是可以哈希化(:Hashable)的类型,即必须提供一个可以计算出自身哈希值的方法。

var a = [101: "张飞", 102:"关羽"]

a[103] = "刘备"

print(a)

let dismissOne = a.removeValueForKey(101)

if dismissOne != nil {

print("\(dismissOne!)")

}

print(a)

a[102] = nil

print(a)

a[103] = "张飞"

print(a)

let replaceOne = a.updateValue("赵云",forKey: 103)

print("\(replaceOne )")

print(a)

a[111] = "sdfsf"

a.removeValueForKey(103)

//遍历

for vkey in a.keys.sort() {

print("\(vkey )")

}

for vvalue in a.values {

print("\(vvalue )")

}

for (id,name) in a {

print("\(id) : \(name)")

}

 类似资料: