Swift基础语法(一)


Swift的语法特点

从它的语法中能看到Objective-C、JavaScript、C#、Python等语言的影子。其借鉴了Objective-C、JavaScript、C#、Python等语言的优点。同时具备编译型语言的高性能和脚本语言的灵活交互性。

编译型语言:就是要保证我们所写的代码全部编译通过,程序才能执行;

脚本语言:你写的代码对一行执行一行,比如你写了10行,第9行有Bug,那么前8行是可以执行成功的

Swift和其它编程语言相比有哪些变化?

1、没有main函数,其它编程语言认为mian函数是程序的入口,Swift认为程序是从上往下一行一行执行的,
因此第一行代码就是程序入口。
2、语句结束时不需要加”;”,当然若你喜欢也是可以加”;”
3、如果同一行有多个语句,则依然需要加”;”,不建议一行写多条语句。
4、定义标识符时必须声明该标识符是变量还是常量。
5、声明标识符的格式:变量/常量关键字 名称:数据类型

(当然你也可以不写数据类型,Swift会自动根据初始值确定其类型),示例如下:

1
2
3
4
5
6
7
8
9
10
// 声明一个String类型的变量
var name:String = "android_ls"
// 声明一个String类型的常量
let desc:String = "做android开发的iOS程序员"
若你不想按上面的格式声明一个变量或者常量,可以采用下面这种写法,示例如下:

// 声明一个String类型的变量
var name = "android_ls"
// 声明一个String类型的常量
let desc = "做android开发的iOS程序员"

6、( )表示初始化也可以表示执行
7、在swift中默认所有的文件共享所有的对象的方法也是默认可以调用
8、命名空间: 在同一个项目下叫做命名空间,在同一个命名空间下所有的文件共享
9、swift 属性默认都是强引用的
10、swift中 init 方法就是构造方法,并且所有的构造方法都叫 init
11、在Swift中,运算符不能直接跟在变量或常量的后面。

Swift中的!和 ?的用法总结

Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会有默认值,
所以要求使用变量之前必须要对其初始化。如果在使用变量之前不进行初始化就会报错:

Optional其实是一个enum枚举值,它有两个值:None和Some。Optional.None其实就是nil,
Optional.Some就是非nil,它会通过Some(T)来进行Wrap包装原始值,
这也是为啥使用Optional类型的时候要进行拆包unWrap(从enum中读取原始值)了。

声明为Optional只需要在类型后面紧跟一个?或者!即可

如:

1
2
3
4
5
6
7
8
var strValue: String?   //?相当于下面这种写法的语法糖
var strValue: Optional<String>
上面的?这个Optional可选项类型声明,意思是我声明了一个Optional类型,而不是声明了一个String类型,
它可能包含一个String值,也可能不包含,不包含默认值就为nil我们可以通过if判断来区分是否为nil

if strValue {
//do something with strValue
}

那么我们怎么使用Optional可选类型的值呢?直接在后面加上一个?号即可。
如果是nil值,也就是Optional.None,会跳过后面的操作不执行,
如果有值,也就是Optional.Some,就会进行unWrap拆包操作,比如:

1
2
3
4
5
6
7
8
 //正确
let hashValue = strValue?.hashValue
//错误
let hashValue = strValue.hashValue

有一种特殊情况,假如我们非常肯定strValue一定是非nil的,我们也可以采用强制拆包处理:使用!
let hashValue = strValue!.hashValue
!就代表强制拆包,假如strValue是nil,你强制拆包也会报错
问号?

a.声明时添加?,告诉编译器这个是Optional的,如果声明时没有手动初始化,就自动初始化为nil。
b.在对变量值操作前添加?,判断如果变量时nil,则不响应后面的方法。

叹号!

a.声明时添加!,告诉编译器这个是Optional的,并且之后对该变量操作的时候,都隐式的在操作前添加!
b.在对变量操作前添加!,表示默认为非nil,直接解包进行处理。不小心让改变量为nil,程序就会crash掉。

swift 中 as as! as? 区别

**(1) as **

仅当一个值的类型在运行时(runtime)和as模式右边的指定类型一致、或者是该类型的子类 的情况下,
才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成as模式左边指定的模式。

1
2
3
4
5
6
7
8
9
10
11
 as 应用条件有2种情况:
1和“as”右边类型一致 =
2是右边类型的子类 <

class ball {}
class football:ball {}
let a = ball()
a as ball //a和右面的ball类型一致,编译成功

let f = football()
f as ball // d 是右面ball的子类,编译成功
(2) as!
1
2
3
4
5
6
7
8
9
10
11
12
如果碰到as左边类型是右边类型的父类,则会报错!as不可以用来父类转子类,这个时候可以用强转 as>

class ball {}
class football:ball {}

let a = ball()
a as ball // 编译成功

let f = football()
a as football // 编译报错

编译器会提醒你用as
(3) as?
1
2
3
4
5
6
7
8
9
as?相当于optional类型,如果强转失败的话会返回nil

class ball {}
class football:ball {}
class basketball:ball {}

let aball:ball = basketball()
aball as? football // 取到的是nil
aball as! football //运行时报错