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<T> : 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<U>(f: @noescape (T) -> U) -> U?
/// Returns `f(self)!` iff `self` and `f(self)` are not nil.
func flatMap<U>(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 运算符 两边要加空格,否则多数时候会报错(赋值 和 比较)
与声明有关的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<T> 对象,是一个连续无关联序列索引的集合。
// .....
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<T> 中的值。
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<String>() //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..<end2!.startIndex] //"Joris"
} 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<end;j=j.successor()){
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..<end //4..<6
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<Int>) -> 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<NSS1.length;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<NSS2.length;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<Array<Int8>>
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<Int> 等价于 var a: [Int]
- var a: Array<Int> = [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<Character> = ["a","e","i","o","u"]
var evenSet:Set = [2,4,5,6]
var set = Set<Int>()
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<Int,String> = [101: "张飞", 102:"关羽"]
var b = Dictionary<Int,String>()
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)")
}
|
请发表评论