Swift已经推出了一段时间了,今天来总结一下Swift与Objective-c(以下简称OC)的语法有哪些不同。
1.常量与变量:
在Swift中定义常量和变量很简单,常量使用let关键字,变量使用var关键字。
var numberOfRows = 30let maxnumberOfRows = 100
在OC中我们声明一个变量的时候需要指定数据类型:
const int count = 10;double price = 23.55;Nsstring *myMessage = @"Objective-C is not dead yet!";
但是在Swift中我们不用,虽然Swift是强类型语言,但是它可以根据赋值进行类型推断:
let count = 10// count会被识别为Intvar price = 23.55// price会被识别为Doublevar myMessage = "Swift is the future!"// myMessage会被识别为String
当然在Swift中写上变量名也不会有任何问题:
var myMessage : String = "Swift is the future!"
2.Swift中不用再写分号了!
在OC中你需要在每一句的后面写上“;”以表达结束,不然会报错,在Swift中你不需要再写分号了,当然你写上也没有问题。
var myMessage = "No semicolon is needed"
3.String
在Swift中字符串的类型是String,不论你定义的是常量字符串还是变量字符串。
let dontModifyMe = "You cannot modify this string"var modifyMe = "You can modify this string"
在OC中你需要使用Nsstring和NSMutableString来区分字符串是否可以被修改。
在Swift中连接两个字符串组成新字符串非常方便,使用“+”:
let firstMessage = "Swift is awesome. "let secondMessage= "What do you think?"var message = firstMessage + secondMessageprintln(message)
println是Swift中一个全局的打印方法。
在OC中我们使用stringWithFormat方法:
Nsstring *firstMessage = @"Swift is awesome. ";Nsstring *secondMessage = @"What do you think?";Nsstring *message = [Nsstring stringWithFormat:@"%@%@",firstMessage,secondMessage];NSLog(@"%@",message);
在OC中要判断两个字符串是否相同你不能用“==”,你需要使用方法isEqualToString方法,但是在Swift中你可以使用“==”来判断字符串是否相同。
var string1 = "Hello"var string2 = "Hello"<pre name="code" >if string1 == string2 { println("Both are the same")}
4.Array数组
数组的用法Swift和OC差不多,我们来看示例:
在OC中:
NSArray *recipes = @[@"Egg Benedict",@"Mushroom Risotto",@"Full Breakfast",@"Hamburger",@"Ham and Egg SanDWich"];
在Swift中:
var recipes = ["Egg Benedict","Mushroom Risotto","Full Breakfast","Hamburger","Ham and EggSanDWich"]
在OC中你可以向NSArray和NSMutableArray中插入任意类型的参数,但是在OC中只能插入相同的参数。
和NSArray相似,Swift中的Array也有很多方法,比如count方法返回数组中的元素个数:
var recipes : [String] = ["Egg Benedict","Ham and Egg SanDWich"]<pre name="code" >var numberOfItems = recipes.count// recipes.count will return 5
在OC中你使用NSMutableArray中的方法addobject来增加数组中的元素,Swift中的方法更简单,你可以使用“+=”,比如:
recipes += ["Thai Shrimp Cake"]不过请注意这个方法是数组间的,如果一个单个元素要加入数组中请在元素外面增加[]。
要取出或者替换数组中的元素,使用索引,这点跟OC中相同:
var recipeItem = recipes[0]recipes[1] = "Cupcake"
在Swift中可以使用Range来表示范围:比如
recipes[1...3] = ["Cheese Cake","Greek Salad","Braised Beef Cheeks"]这里替换的是recipes中的第二到第四个元素。
5.Dictionary字典
字典是一种集合类型,由键值对组成,这一点和OC中的NSDictionary很类似,请看示例:
OC中:
NSDictionary *companIEs = @{@"AAPL" : @"Apple Inc",@"GOOG" : @"Google Inc",@"AMZN" :@"Amazon.com,Inc",@"FB" : @"Facebook Inc"};
Swift中:
var companIEs = ["AAPL" : "Apple Inc","GOOG" : "Google Inc","AMZN" : "Amazon.com,"FB" : "Facebook Inc"]你也可以声明它的字典类型:
var companIEs: Dictionary<String,String> = ["AAPL" : "Apple Inc","FB" : "Facebook Inc"]
要遍历一个字典,需要使用元组来保存每一次循环的字典中的信息:
for (stockCode,name) in companIEs { println("\(stockCode) = \(name)")}
你也可以单独遍历字典中的键或者值:
for stockCode in companIEs.keys { println("Stock code = \(stockCode)")}for name in companIEs.values { println("Company name = \(name)")}
如果想给字典添加新的键值对,那么使用如下语句:
companIEs["TWTR"] = "Twitter Inc"
6.Class类
在OC中创建类的话,会得到两个文件,一个接口文件(.h文件)和一个实现文件(.m文件)。
而在Swift中生成类只有一个文件.swift文件。
示例:
class Recipe { var name: String = "" var duration: Int = 10 var ingredIEnts: [String] = ["egg"]}
在上面的示例中我们创建了一个Recipe类,里面有三个属性,并且都声明了类型,做了初始化。在Swift中类在初始化的时候它的属性必须都被初始化。如果你不想设置某个属性的默认值的话,使用?把它加入可选链中:
class Recipe { var name: String? var duration: Int = 10 var ingredIEnts: [String]?}这样当你创建一个类的实例的时候:
var recipeItem = Recipe()
这些可选链中的属性的初始值是nil。你可以给它们赋值:
recipeItem.name = "Mushroom Risotto"recipeItem.duration = 30recipeItem.ingredIEnts = ["1 tbsp drIEd porcini mushrooms","2 tbsp olive oil","1 onion,chopped","2 garlic cloves","350g/12oz arborio rice","1.2 litres/2 pints hot vegetablestock","salt and pepper","25g/1oz butter"]
类可以继承父类和遵守协议,示例:
OC中:
@interface SimpletableVIEwController : UIVIEwController <UItableVIEwDelegate,UItableVIEwDataSource>
Swift中:
class SimpletableVIEwController : UIVIEwController,UItableVIEwDelegate,UItableVIEwDataSource
7.Methods方法
Swift允许你在类、结构体和枚举中创建方法。
下面是一个没有参数和返回值的方法:
class TodoManager { func printWelcomeMessage() { println("Welcome to My Todo List") }}
在OC中调用一个方法的格式如下:
todoManager printWelcomeMessage];
在Swift中调用一个方法的格式如下:
todoManager.printWelcomeMessage()
如果要建立一个带参数和返回值的方法,格式如下:
class TodoManager { func printWelcomeMessage(name:String) -> Int { println("Welcome to \(name)'s Todo List")return 10 }}
"->"用来指示方法的返回值类型。
你可以这样调用上面的方法:
var todoManager = TodoManager()let numberOfTodoItem = todoManager.printWelcomeMessage("Simon")println(numberOfTodoItem)
8.Control Flow控制流
Swift中的控制流和循环颇有C语言的风格。
8.1for循环
for循环使用 for - in的结构,并且可以和Range(...或者..<)配合使用:
for i in 0..<5 { println("index = \(i)")}
会在控制台输出:
index = 0
index = 1
index = 2
index = 3
index = 4
如果我们使用...这是个闭集合,结果会返回:
index = 4
index = 5
如果你想用c中的结构也是可以的:for var i = 0; i < 5; i++ { println("index = \(i)")}
只不过for后面不用写括号了。
8.2 if-else结构
和OC中很像,只不过Swift中更简单一些,条件语句不需要写在括号中:
var bookPrice = 1000;if bookPrice >= 999 { println("hey,the book is expensive")} else { println("Okay,I can affort it")}
8.3 switch结构
Switch中的switch结构拥有非常强大的功能。
示例:
switch recipename { case "Egg Benedict": println("Let's cook!") case "Mushroom Risotto": println("Hmm... let me think about it") case "Hamburger": println("love it!") default:}println("Anything else")
首先Swift中的switch中可以控制字符串,OC中的Nsstring是不能被switch控制的,在OC中要实现类似功能你只能使用if-else。
另外你可以看到在每个case中我们都没有写break,在OC中你必须在每个case中写break,否则在当前case结束后会进入下一个case,在Swift中当前case被执行后就会自动跳出switch,如果需要进入下一个case,添加fallthrough语句。
最后,switch的case中可以包含Range *** 作:
var speed = 50switch speed {case 0: println("stop")case 0...40: println("slow")case 41...70: println("normal")case 71..<101: println("fast")default: println("not classifIEd yet")}
9.Tuple元组
元组类型在OC中是没有的,它可以包含多种不同的数据类型,你可以把它用作方法的返回值,这样就可以用一个元组来代替返回一个复杂的对象了。例如:
let company = ("AAPL","Apple Inc",93.5)
你可以把元组company中的值取出来,用法如下:
let (stockCode,companyname,stockPrice) = companyprintln("stock code = \(stockCode)")println("company name = \(companyname)")println("stock price = \(stockPrice)")
或者company.0、company.1这样的方法也能取到值,更好的做法是在定义元组的时候给每个元素起个名字:
let product = (ID: "AP234",name: "iPhone 6",price: 599)println("ID = \(product.ID)")println("name = \(product.name)")println("price = USD\(product.price)")
下面是一个把元组作为返回类型的例子:
class Store { func getProduct(number: Int) -> (ID: String,name: String,price: Int) { var ID = "IP435",name = "iMac",price = 1399 switch number { case 1: ID = "AP234" name = "iPhone 6" price = 599 case 2: ID = "PE645" name = "iPad Air" price = 499default:<span >break }</span><pre name="code" > return (ID,name,price) }}
调用:
let store = Store()let product = store.getProduct(2)println("ID = \(product.ID)")println("name = \(product.name)")println("price = USD\(product.price)")
10.Optional可选型
10.1可选型
可选型通常用在变量之中,可选型的默认值是nil。如果你给一个非可选型的变量赋值nil会报错:
var message: String = "Swift is awesome!" // OKmessage = nil // compile-time error
当你的类中的属性没有全部初始化的时候会报错:
class Messenger { var message1: String = "Swift is awesome!" // OK var message2: String // compile-time error}
在OC中当你给变量赋值为nil或者没有初始化属性的时候,你是不会收到一个编译时错误的:
Nsstring *message = @"Objective-C will never dIE!";message = nil;class Messenger { Nsstring *message1 = @"Objective will never dIE!"; Nsstring *message2;<span >}</span>
但这不代表你不可以在Swift使用没有初始化的属性,我们可以使用?来表示这是一个可选型的变量:
class Messenger { var message1: String = "Swift is awesome!" // OK var message2: String? // OK}
10.2那么我们为什么要用可选型呢?
Swift语言设计的时候有很多安全方面的考虑,可选型表示了Swift是一门类型安全的语言,从上面的例子中你可以看到Swift中的可选型会在编译时就去检查某些可能发生在运行时的错误。
考虑下面的OC中的方法:
- (Nsstring *)findStockCode:(Nsstring *)company { if ([company isEqualToString:@"Apple"]) { return @"AAPL"; } else if ([company isEqualToString:@"Google"]) { return @"GOOG"; }return nil; }
这个方法用来判断输入的字符串是不是Apple和Google,如果是其他的话返回nil。
假设我们在类中定义这个方法,并且在类中使用它:
Nsstring *stockCode = [self findStockCode:@"Facebook"]; // nil is returned<pre name="code" >Nsstring *text = @"Stock Code - ";Nsstring *message = [text stringByAppendingString:stockCode]; // runtime errorNSLog(@"%@",message);
这段代码是可以通过编译的,但是会在运行时发生错误,原因就是方法中传入FaceBook返回了nil。
上面OC中的代码我们在Swift中的话是这样写的:
func findStockCode(company: String) -> String? { if (company == "Apple") { return "AAPL" } else if (company == "Google") { return "GOOG" }return nil }<pre name="code" >var stockCode:String? = findStockCode("Facebook")let text = "Stock Code - "let message = text + stockCode // compile-time errorprintln(message)
这段代码不能通过编译,可以避免运行时的错误了。显而易见,可选型的应用可以提高代码的质量。
10.3解包可选型
在上面我们已经看到了可选型的用法,那么我们如何判断一个可选型的变量有值还是为nil呢?
示例:
var stockCode:String? = findStockCode("Facebook")let text = "Stock Code - "if stockCode != nil { let message = text + stockCode! println(message)}
很像OC中的配对,我们使用if判断语句来做可选型的空值判断。一旦我们知道可选型肯定有值的时候,我们可以使用强制拆封(或者叫解包),也就是在变量名后面加一个感叹号来取得变量的值。
如果我们忘记做空值判断会怎样?你进形了强制拆封所以不会发生编译时错误
var stockCode:String? = findStockCode("Facebook")let text = "Stock Code - "let message = text + stockCode! // runtime error
会发生运行时错误,错误提示:
Can’t unwrap Optional.None
10.4可选绑定
除了强制拆封,可选绑定是一个更简单更好的做法。你使用if - let结构的可选绑定来判断一个变量是不是空值
示例:
var stockCode:String? = findStockCode("Facebook")let text = "Stock Code - "if let tempStockCode = stockCode { let message = text + tempStockCode println(message)}
if let的意思是如果stockCode有值,那么解包它,并且把它赋给一个临时变量tempStockCode,并且执行下面大括号中(条件块)的代码,否则跳过大括号中的代码。
因为tempStockCode是一个新的常量,你不必再使用!来获取它的值。
你可以简化这个过程:
let text = "Stock Code - "if var stockCode = findStockCode("Apple") { let message = text + stockCode println(message)}
我们把stockCode的定义放到if中,这里stockCode不是可选型,所以在下面的大括号中也不用再使用!如果它是nil,那么大括号中的代码就不会执行。
10.5可选链
我们有一个类Code,里面有两个属性code和price,它们的类型是可选型。把上面示例中的stockCode方法的返回值由String改为返回一个Code类型。
class Stock { var code: String? var price: Double?}func findStockCode(company: String) -> Stock? { if (company == "Apple") { let aapl: Stock = Stock() aapl.code = "AAPL" aapl.price = 90.32return aapl } else if (company == "Google") { let goog: Stock = Stock() goog.code = "GOOG" goog.price = 556.36return goog }return nil }
现在我们计算买了100个苹果需要多少钱:
if let stock = findStockCode("Apple") { if let sharePrice = stock.price { let totalCost = sharePrice * 100 println(totalCost) }}
因为findStockCode的返回值是可选值,我们使用可选绑定来判断,但是Stock的price属性也是可选的,所以我们又用了一个可选绑定来判断空值。
上面的代码运行没有问题,不用if let我们有更简单的办法,你可以把上面的代码改成可选链的 *** 作,这个特性允许我们把多个可选类型用?连接,做法如下:
if let sharePrice = findStockCode("Apple")?.price { let totalCost = sharePrice * 100 println(totalCost)}总结
以上是内存溢出为你收集整理的Swift 与Objective-c语法参照全部内容,希望文章能够帮你解决Swift 与Objective-c语法参照所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)