Swift学习笔记 ——(一)
前言
作为一个前端开发者,经常与javaacript(以下简称:js)打交道。最近想了解一下ios开发,前两天看了一下objective-c(以下简称:oc),相对于js来说还是有很多不同的,但是语言还是很多相通的地方,加上之前了解一些java,理解起来不是很困难。
在网上看了很多对oc和swift的评价,褒贬不一,心里想着,如果是ios开发的话,这两种肯定都要学,所以这两天对swift进行了了解。对习惯js的我来说,swift写起来简直不要太舒服,与oc写起来差别还是挺大的。
后来想到,还是记录下来比较好,过两天有时间把oc的笔记也整理一下,方便以后查看,如果自己理解的有问题还可以请大家指正。
注:有兴趣的可以查看苹果开发者、Swift官网以及这个Swift的语法指南。以下是我在看过之后结合网站上的内容加上自己的一些理解整理出来的。
有兴趣可以看一下这个东西,很好用,下面进入正题。
-
swift打印使用
print
,而oc使用的则是NSLog
print("hello world!");
-
swift中定义变量使用
var
和let
,其中let
为常量,定义的时候必须赋初值。使用var
声明变量并不表示弱类型,而是在初始化的时候就识别变量的类型,之后修改变量的值必须是初始化的数据类型。var name = "Tom"; name = 20; // 报错,因为初始化是String类型,不可以赋值为Int类型 let age = 18; // 如果想要默认为空 var str: String? = nil;
-
swift中字符串只能使用双引号,不可以使用单引号。
var firstName = "Tom"; // 正确 var lastName = 'James'; // 报错
-
在swift中没有隐式类型转换,必须手动转换类型,如:
var str1 = "hello world"; var num1 = 666; var concatStr = str1 + String(num1);
-
swift字符串拼接使用
\()
,如:var name = "Tom"; var age = 18; print("this is name \(name)"); // this is name Tom print("this is age \(age)"); // this is age 18
在这里数字直接与字符串进行拼接。
多行字符串拼接使用
"""
, 如:var age = 18; var str = """ this is a Tom heihei\(age) """; print(str); // this is a // Tom // heihei18
-
swift可以创建类型为”数组”和”字典”两种数据格式,有两种方式:
两种类型分别是一下这种形式:
数组:[1, 2, 3] 或者 [“Tom”, “James”]
字典:[“firstName”: “Tom”, “lastName”: “James”]1).直接赋值 var array = ["aa", "bb"]; var dictionary = ["aa": "Tom", "bb": "James"]; // 调用或修改其中的值 array[1] = "cc"; dictionary["aa"] = "Jerry"; print(array); // ["aa", "cc"] print(dictionary); // ["aa": "Jerry", "bb": "James"] 2).声明 var array = [String](); // [] var dictionary = [String:String](); // [:] //如果在声明之后重新清空可以直接赋值: array = []; dictionary = [:]; // 给空数组或者字典赋值: array.append("hello"); dictionary["hello"] = "world";
-
可以使用
??
来过滤optional为nil
的值:var firstName: String? = nil; var lastName: String = "world"; var info = "Hi \(firstName ?? lastName)"; print(info); // "Hi world"
-
swift中
if
和for
相对简单,这里就举一个简单的例子:// 如果是数组类型 var arrs = [1,2,3,4,5]; var count = 0; for arr in arrs { if arr>2 { // 同if(arr>2),这里的括号可加可不加 count += 1; } } print(count); // 3 // 如果是字典类型 var dictionary = ["first": 1, "second": 2, "third": 3]; for (name, number) in dictionary { print("name is \(name)"); // name分别为:"first" "second" "third" print("number is \(number)"); // number分别为:1 2 3 }
-
switch语法结构与其他语言没什么变化:
var selected = "hello world"; switch selected { case "hello": print("This is hello"); case "objective-c", "swift": print("This is objective-c or swift"); case "hello world": print("This is hello world"); default: print("Everying is no test!"); }
注意:
- switch必须存在default,否则会报错;
- 不需要break来退出条件判断,如果匹配到对应的case,只会执行对应的代码,然后退出条件判断。
- 在case中可以使用函数,比如我们可以将上述代码中的第三个case改成这样:case let x where x.hasSuffix("world"):
输出是一样的,这里就执行了一个函数hasSuffix
。
hasSuffix:这个函数是swift提供的一个匹配后缀的函数,返回布尔值。 -
while循环
普通的
while
循环,while
后面跟着循环条件,大括号里面是循环体:var n = 2; while n < 100 { n *= 2; } print(n); // 128
在swift中有个关键字
repeat
,循环体写在repeat
里面:var m = 2 repeat { m *= 2 } while m < 100 print(m); // 128
repeat跟其他语言中do…while中的do是一样的。
-
在swift中表示范围可以用
...
,..<
表达式// 1~5之间,包括1和5 1...5 // [1,5] // 1~5之间,包括1,但不包括5 1..<5 // [1,5)
-
swift中的函数
函数的定义,用func关键字,后面跟函数名,括号里为参数名及类型,->
紧跟的的是返回值的类型,如:func getName(firstName: String, lastName: String) -> String { return "Hello, \(firstName) \(lastName)." }
函数调用:
getName(firstName: "hello", lastName: "world");
每个参数前面可以有一个标签,就像这样:
func getName(first firstName: String, last lastName: String) -> String { // to do }
然后在传入参数的时候可以使用这个标签来传递,就像这样:
getName(first: "Tom", last: "James");
当然也可以省略标签,swift中提供了一种形式,用
_
表示标签,就像这样:func getName(_ firstName: String,_ lastName: String) -> String { // to do }
然后在调用
getName
方法的时候,就可以这样传参:getName("Tom", "James");
-
函数作用域
在swift中也是有作用域的,在一个函数内部声明的变量在函数外部是无法访问的,内部可以随意访问(包括内部声明的其他函数)。
就像这样:func calc() -> Int { var a = 1; a += 1; return a; } print(a); // 报错, error: use of unresolved identifier 'a'
当然内部函数调用是没问题的:
func calc() -> ((Int) -> Int) { var a = 1; func calcSub(number: Int) -> Int { a += number; return a; } return calcSub; } var result = calc(); print(result(2)); // 3
- 这里swift是支持返回函数的,一个函数可以用另一个函数来当作返回值,返回的是一个函数的声明,如果调用还需要使用
result()
去调用。
同理,传入的参数也可以是函数,结构是这样的:
func calc(number: Int, addFunc: (Int) -> Bool) -> Int { // to do addFunc(1); return 0; } func add(number: Int) -> Bool { if(number > 5) { return true; } return false; } calc(number: 123, addFunc: add);
- 这里swift是支持返回函数的,一个函数可以用另一个函数来当作返回值,返回的是一个函数的声明,如果调用还需要使用
-
闭包
由于外部函数A无法调用另一个函数B内部的变量,但是如果在函数B的内部声明一个函数C,同时,在函数B中将函数C暴露出去,函数C由于是函数B内部的函数,是可以调用函数B中定义的变量的,那么我们在外面调用函数C就可以操作函数B内部的变量了,这就是闭包了。
说的可能比较抽象,所以我简单画了一张图:因为A是无法访问变量
a
的所以通过C间接操作变量a
。这里官网文档给出了两个例子,分别使用了
map
和sorted
这两个函数。var numbers = [1, 2, 3]; // 使用map函数 numbers.map({ (number: Int) -> Int in let result = 3 * number return result }) // 如果已经知道类型就可以简化上面的写法 let mappedNumbers = numbers.map({ number in 3 * number }) print(mappedNumbers) /* *map函数遍历上述numbers数组,number依次为每一项的值 *`in`后面可以理解为返回值 *这里是将number操作后返回 * */
let sortedNumbers = numbers.sorted { $0 > $1 } print(sortedNumbers) /* *sorted为排序函数 *$0表示前一个值,$1表示后一个值 *后面大括号里是排序的规则 *这里的$0 > $1,即"降序排列" */
写在后面
感觉太长了看起来很难受,欲望贼低,所以准备分开成写,这样比较舒服一些。