Swift 3那些不同以往的特性
2017-03-27 14:35
183 查看
原文:http://www.jianshu.com/p/5d911fae5b2f
Swift 3改变可以分为两个大的部分
1.移除在
2.语言更加安全,优雅(正确的废话)
自增自减操作符是从
对于初学者而言可能有些奇怪,所以被移除了。使用
大多数语言都是使用
以前可以写:
在
你也可以用闭包和快捷参数来使用
方法参数通常被定义为常量,因为不需要在函数内部修改它,然后有些情况下当把声明作为变量的时候可能会更加方便。在
下面一个例子,用于求两个数的最大公约数:
算法比较简单,
在
因此,用
方法参数列表是以元组的形式,所以可以使用元组来调用函数,只要元组的结构和方法参数的结构一样,用
或者可以
正如你所见,你不需要给第一个参数具体化在
这样的语法对于初学者而言具有迷惑性,所以使用标准的形式,在
你不得不给第一个参数精确地修饰符,如果不这样做,Xcode 8直接就会报错。
可能看到这样的改变,会觉得那我以前的代码如何兼容呢,为了兼容以前的,苹果推出一种方式来解决。如下:
这样改变了方法名称之后,就能兼容之前调用的方式了。
常见的我们在创建一个
重点看一下
为了解决这个潜在的问题,
和
之前的方式:
如果
在
如下:
提及
比如之前:
通过
在
纯手写码字有点累,下面还是直接给代码。
之前
之前是使用
之后
之前
之后(通过对象的方式调用)
比如:
在
使用
Swift 3改变可以分为两个大的部分
1.移除在
Swift 2.2中弃用的方法
2.语言更加安全,优雅(正确的废话)
++和--操作符
自增自减操作符是从C搬过来的,非常快捷来增加或者减少1.
var i = 0 i++ ++i i-- --i
对于初学者而言可能有些奇怪,所以被移除了。使用
+=或者
-=来赋值操作。当然也可以通过操作符重载来实现上诉的功能。
var i = 0 i += 1 i -= 1
C与语言风格的循环已经成为历史
大多数语言都是使用C语言风格的操作符来表示循环。移除这个操作意味着以后就不能用了。因为用
for-in操作完全可以替代的。
以前可以写:
for (i = 1; i <= 10; i++) { print(i) }
在
Swift3中,不允许这样的写法,用
...表示的范围
for i in 1...10 { print(i) }
你也可以用闭包和快捷参数来使用
for-each
for i in 1...10 { print(i) }
移除方法参数的var
声明
方法参数通常被定义为常量,因为不需要在函数内部修改它,然后有些情况下当把声明作为变量的时候可能会更加方便。在Swift2中,可以通过关键字
var标记一个方法参数作为变量,一旦方法参数用
var修饰,将会创建一份对于参数的
Copy。所以你可以在函数内部修改它的值。
下面一个例子,用于求两个数的最大公约数:
func gcd(var a: Int, var b: Int) -> Int { if (a == b) { return a } repeat { if (a > b) { a = a - b } else { b = b - a } } while (a != b) return a }
算法比较简单,
在
Swift3中不运行设置方法参数作为变量,因为
Swift开发者可能会因为
var和
inout而标的疑惑。所以最新的版本移除了方法参数中的
var
因此,用
Swift3中的语法,达到这样的目的需要用不同的方法,比如需要去保存方法参数作为本丢变量。
func gcd(a: Int, b: Int) -> Int { if (a == b) { return a } var c = a var d = b repeat { if (c > d) { c = c - d } else { d = d - c } } while (c != d) return c }
扩展方法参数的形式
方法参数列表是以元组的形式,所以可以使用元组来调用函数,只要元组的结构和方法参数的结构一样,用gcd()做一个例子。
gcd(8, b: 12)可以这样调用
或者可以
let number = (8, b: 12) gcd(number)
正如你所见,你不需要给第一个参数具体化在
Swift2,然后你不得不在调用方法的时候具体化第二个参数。
这样的语法对于初学者而言具有迷惑性,所以使用标准的形式,在
Swift3中,如下调用:
gcd(a: 8, b: 12)
你不得不给第一个参数精确地修饰符,如果不这样做,Xcode 8直接就会报错。
可能看到这样的改变,会觉得那我以前的代码如何兼容呢,为了兼容以前的,苹果推出一种方式来解决。如下:
func gcd(_ a: Int, b: Int) -> Int { ... }
这样改变了方法名称之后,就能兼容之前调用的方式了。
Seletors 作为字符串不在起作用
常见的我们在创建一个button之后,然后会给它加上点击事件,比如:
//1 import UIKit import XCPlayground // 2 class Responder: NSObject { func tap() { print("Button pressed") } } let responder = Responder() // 3 let button = UIButton(type: .System) button.setTitle("Button", forState: .Normal) button.addTarget(responder, action: "tap", forControlEvents: .TouchUpInside) button.sizeToFit() button.center = CGPoint(x: 50, y: 25) // 4 let frame = CGRect(x: 0, y: 0, width: 100, height: 50) let view = UIView(frame: frame) view.addSubview(button) XCPlaygroundPage.currentPage.liveView = view
重点看一下
button.addTarget(responder, action: "tap", forControlEvents: .TouchUpInside)这句话,
button的
selector是字符串,如果写的类型错了,能够编译通过,但是会在运行的时候崩溃。因为没有可以响应的方法。
为了解决这个潜在的问题,
Swift3用
#selector()关键字替换了字符串类型的
selectors。这种方式可以让编译器在编译的时候,如果不存在这样的方法名就能直接报出编译错误,代码如下:
btton.addTarget(responder, action: #selector(Responder.tap), for: .touchUpInside)
Key-paths 作为字符串
和Seletors作为字符串不在起作用类似,只不过将这种特性运用到了
KVC(键值编码)和
KVO(观察者):
之前的方式:
class Person: NSObject { var name: String = "" init(name: String) { self.name = name } } let me = Person(name: "Cosmin") me.valueForKeyPath("name")
如果
me.valueForKeyPath("name")中不存在属性
name,运行到这段代码必将崩溃。
在
Swift3中就不用担心,
Key-Path已经用
#keyPath()代替。
如下:
class Person: NSObject { var name: String = "" init(name: String) { self.name = name } } let me = Person(name: "Cosmin") me.value(forKeyPath: #keyPath(Person.name))
从Foundation类型中去掉NS前缀
提及NS前缀,大家应该知道是
Next-Step的缩写吧。但是
Swift毕竟是一门崭新的语言,所以从前缀上就能之前的习惯做了区分。可以看出,这也是未来
Swift会大行其道的预兆。
比如之前:
let file = NSBundle.mainBundle().pathForResource("tutorials", ofType: "json") let url = NSURL(fileURLWithPath: file!) let data = NSData(contentsOfURL: url) let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: []) print(json)
通过
Foundation中的类从文件中读取
json数据,中间用到了
NSBundle -> NSURL -> NSData -> NSJSONSerialization.
在
Swift3中,前缀被移除,看起来更加优雅
let file = Bundle.main().pathForResource("tutorials", ofType: "json") let url = URL(fileURLWithPath: file!) let data = try! Data(contentsOf: url) let json = try! JSONSerialization.jsonObject(with: data) print(json)
纯手写码字有点累,下面还是直接给代码。
M_PI vs .pi
之前let r = 3.0 let circumference = 2 * M_PI * r let area = M_PI * r * r
之前是使用
M_PI指代
pi常量,
Swift3中分别在
Float,Double,CGFloat几种类型中指代了
pi常量。
之后
let r = 3.0 let circumference = 2 * Double.pi * r let area = Double.pi * r * r
GCD
之前let queue = dispatch_queue_create("Swift 2.2", nil) dispatch_async(queue) { print("Swift 2.2 queue") }
之后(通过对象的方式调用)
let queue = DispatchQueue(label: "Swift 3") queue.async { print("Swift 3 queue") }
枚举
Swift3中将枚举
case看起来像属性,所以使用小写的方式表示了系统的而一些枚举值:
比如:
.System becomes .system .TouchUpInside becomes .touchUpInside .FillStroke becomes .fillStroke .CGColor becomes .cgColor
关键字@discardableResult
在Swift3中,如果没有使用方法的返回值,会报出警告。如下:
使用
@discardableResult关键字取消警告
override func viewDidLoad() { super.viewDidLoad() printMessage(message: "Hello Swift 3!") } @discardableResult func printMessage(message: String) -> String { let outputMessage = "Output : \(message)" print(outputMessage) return outputMessage }
相关文章推荐
- Swift - Swift 3 新特性汇总(不同于以往版本的新变化)
- 【转载】Android N 完全不同以往的四个新特性
- Swift - Swift 3 新特性汇总(不同于以往版本的新变化)
- Android N 完全不同以往的四个新特性
- Swift - Swift 3 新特性汇总(不同于以往版本的新变化)
- iOS 8 中新特性 - Swift 编程语言,一种接近自然语言的开发语言
- Swift 2.0初探:值得注意的新特性
- Swift 中最好的新特性
- Swift 笔记 七:swift函数的高级特性
- Swift——(五)Swift中的那些默认值
- 和以往印象不同的Java
- Oracle 12C 新特性之 db默认字符集AL32UTF8、PDB支持不同字符集
- 你能描述一下渐进增强和优雅降级之间的不同吗?如果提到了特性检测,可以加分。
- 理解 Lua 的那些坑爹特性
- 理解 Lua 的那些坑爹特性
- C#6.0 中的那些新特性
- Swift3新增特性(一)
- Swift语言中与C-C++和Java不同的语法(四)
- C/C++中的那些不同:结构体和联合体
- VS2015 C#6.0 中的那些新特性