swift 3.0 基础语法
目录
01-变量和常量
02-运算符
03-可选项
04-条件语句
05-循环
06-字符串
07-元组
08-数组
09-字典
10-对象和类
11-枚举
12-属性
13-下标脚本
01-变量和常量
1.1基本数据类型
1.整数: Int
2.浮点数: Double表示64位浮点数,Float表示32位浮点数
3.布尔类型: Bool,布尔值只有 true 和 false 两种
4.字符串: String
5.字符: Character
1.2变量和常量
1.变量:值能被修改,var 修饰
2.常量:值不能被修改,let 修饰
var a =
20
a =
10
let b =
20
//b = 10 常量不能修改:error:'b' is a 'let' constant
1.会自动推导声明的变量或常量的属性
2.使用【option + 单击】键查看属性的类型
// 1.自动推导类型
let str =
"ningcol"
let intValue =
10
let floatValue =
1.2
// 2.指定数据类型
let doubleValue:Double =
10
02-运算符
1基本运算符
var a = 5let b = 3
// 1.赋值运算符
let c = b
// 2.加减乘除
1 + 2
5 - 3
2 * 3
10.0 / 2.5
2任何情况下都不会做隐式转化,必须以相同类型进行计算
let num1 =
1
let num2 =
2.2
let num3 = Double(num1) + num2
3必须要显式类型的转化
let j =
2.2
let i:Float =
1.2
i + Float(j)
4.求余运算
a % b
5负号运算
let minusB = -b
6.组合赋值运算
a +=
2
7.比较运算
1 ==
1
2 !=
1
2 >
1
1 <
2
1 >=
1
2 <=
1
8.三目运算
let d = a > b ?
100 :
200
9.空合运算
1.空合运算符( a ?? b )将对可选类型 a 进行空判断(可选项内容详见:04-可选项)
2.如果 aName 为 nil,则执行??后面的,否则执行aName(注意??两边都有空格)
var aName: String? =
"ningcol"
//var aName: String? = nil
let bName = aName ??
"aNameIsNil"
10.区间运算
1.闭区间运算符( a...b )定义一个包含从 a 到 b (包括 a 和 b )的所有值的区间
2.半开区间( a..<b )定义一个从 a 到 b 但不包括 b 的区间
for index in 1...5 {
print(index)
}
for index in 1..<5 {
print("半开区间:\(index)")
}
11.逻辑运算
1.逻辑非(!a):布尔值取反
2.逻辑与( a && b ):只有 a 和 b 的值都为 true 时,整个表达式的值才会是 true
3.逻辑或( a || b ):两个逻辑表达式的其中一个为 tru e ,整个表达式就为 true
let allowedEntry =
false
let enteredDoorCode =
true
if !
allowedEntry {
print("ACCESS DENIED")
}
if allowedEntry &&
enteredDoorCode {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
if allowedEntry ||
enteredDoorCode {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
03-可选项
1.可选值
可选值:可以有值,可以为nil(用 ? 表示可选值)
// URL 为可选项
let URL = NSURL(
string:
"http://www.baidu.com/")
// str 为可选项
var str: String? =
"ningcol"
// var 的可选项默认为 nil
var a:Int?
print(a)
2 if let 语句
// if let : 确保 myUrl 有值,才会进入分支
if let myUrl =
URL{
print(myUrl)
}
var aName: String? =
"ningcol"
// var aName: String? = nil
var aAge: Int? =
18
if let name = aName,let age =
aAge {
print(name +
String(age))
}
// 可以对值进行修改
if var name = aName,let age =
aAge {
name =
"lisi"
print(name +
String(age))
}
3.guard let
1.guard let 和 if let 相反。表示一定有值,没有就直接返回
2.降低分支层次结构
3.playground不能展示效果,要在函数中展示
// 创建一个类(详见:10-对象和类)
class test{
func demo(){
let aNick: String? =
"ningcol"
let aAge: Int? =
10
guard let nick = aNick ,let age = aAge
else {
print("nil")
return
}
print("guard let: " + nick +
String(age))
}
}
var t =
test()
t.demo()
4.强制解包
// 创建一个数组(详见:08-组数)
var dataList:[String]?
dataList = [
"zhangsan",
"lisi"]
/*********************************************************************
1.dataList? 表示 datalist 可能为 nil
2.如果为 nil, .count 不会报错,仍然返回 nil
2.如果不为 nil,.count执行,返回数组元素个数
4. ?? 空合运算符(详见:02-运算符)
*********************************************************************/
let count = dataList?.count ??
0
// 表示 datalist 一定有值,否则会出错!
let cou = dataList!.count
04-条件语句
4.1.if语句
/*********************************************************************
1.必须要有大括号
2.没有"非零即真"的概念,只有ture/false
*********************************************************************/
let num =
20
if num >
10{
print("大于10");
}else{
print("小于或等于10")
}
4.2switch
/*********************************************************************
1.值可以是任何类型
2.作用域仅在 case 内部
3.不需要 break
4.每一个 case 都要有代码
*********************************************************************/
let name =
"nick"
switch name {
case "nick":
let age =
18
print("one \(age)")
case "fil":
print("two")
case "Davi":
print("three")
case "":
break //相当于有一行代码
case "tom",
"ningcol":
print("tomAndNingcol")
default:
print("other")
}
switch分支使用范围
let count =
3_000
var naturalThings:String
switch count{
case 0:
naturalThings =
"数字0"
case 1...
3:
naturalThings =
"数字1-3"
case 4...
9:
naturalThings =
"数字4-9"
case 10...
99:
naturalThings =
"数字10-99"
case 1000...
9999:
naturalThings =
"数字1000-9999"
default:
naturalThings =
"数字9999以上"
}
print(naturalThings);
//输出:数字1000-9999
05-循环
5.1 for循环
// 去掉了C语言风格的循环( ..< 区间运算符,详见:02-预算符)
for i
in 0..<
10{
print(i)
}
print("----步长循环-----")
// 递增(步数为2)
for i
in stride(from:
0, to:
12, by:
2) {
print(i)
}
print("开始递减")
// 递减
for i
in stride(from:
12, to:
0, by: -
2) {
print(i)
}
print("----反序循环----")
let range =
0...
10
// 反序循环
for i
in range.reversed(){
print(i)
}
5.2循环结构while
/*
while语句,只有当 ip<5 为 false 才跳出 while语句
*/
var ip = 0
while (ip<5){
print("ip=\(ip)")
ip += 1
}
//运行结果
//ip=0
//ip=1
//ip=2
//ip=3
//ip=4
/*
repeat-while 循环,不管pa是多少,先执行一次,在判断,为false 跳出 do while语句
*/
var pa = 5 repeat{ print("pa=\(pa)") pa += 1 }while (pa<5) //运行结果 //pa=5
06-字符串
1.String 结构体,效率比对象高,一般推荐使用,支持遍历
2.NSString 继承NSObject
var str:String =
"Hello你好"
//var st:NSString = "hah"
// 字节数量
print(str.lengthOfBytes(
using: .utf8))
// 字符串长度
print(str.characters.count)
for a
in str.characters{
print(a)
}
// 字符串拼接
let name:String? =
"老王"
let age =
80
let location =
"隔壁"
print(location + (name ??
"a") + String(age) +
"岁")
// '\(变量名)' 会自动转换拼接
print(
"\(location)\(name)\(age)岁")
let rect = CGRect(x:
0, y:
0, width:
100, height:
100)
print("\(rect)")
// 格式字符串
let h =
13
let m =
5
let s =
9
let timeStr = String(format:
"d:d:d", arguments: [h,m,s])
let timeStr1 = String(format:
"d:d:d", h,m,s)
1.在Swift中使用 Range,最好把 String 改成 NSString
2.str.substring(with: Range<String.Index>) 很麻烦
3. '值 as 类型' 作为类型转换
(str
as NSString).substring(with: NSMakeRange(
2,
5))
let index = str.index(str.startIndex, offsetBy:
3)
str.substring(from: index)
// "123"只是用来取到索引位置
str.substring(from:
"123".endIndex)
print("****\(str.substring(from: "123".endIndex))")
str.substring(to: index)
String 使用 Range
let myRange = str.startIndex..<str.index(str.startIndex, offsetBy:
5)
str.substring(with: myRange)
let myRange1 = index..<str.index(str.startIndex, offsetBy:
5)
str.substring(with: myRange1)
07-元组
// 元组的元素个数固定,不允许增加、删除
var stu = (
404,
"小白")
// 支持嵌套
var msg = (
"基本信息", (
"李刚",
34))
print(stu)
print(msg)
var (a,b) =
stu
print(a,b)
//如果仅需要元组中的个别的值,可以使用"_"的方式来处理不需要的值
let (c,_) =
stu
print(c)
//通过序号获得元组的值
print(
"status is \(stu.0)")
// 可以修改
stu.
0 =
500
let message = (status:
100, msg:
"哈哈")
print("message is \(message.status) and \(message.msg)")
08-数组
8.1 数组定义
使用let修饰的数组是不可变数组
使用var修饰的数组是可变数组
//方括号 [] 来创建数组
let array1 = [
"zhangsan",
"lisi"]
let array2 = [
1,
2,
3,
4,
5]
var array3:[Int] // 定义一个数组(没有初始化)
array3 = [Int]()
//初始化
//声明空数组,(必须初始化)
let array4 = [String]()
// 等价上面两行代码
let array5:[Any] = [
"zhangsan",
"lisi",
20]
var arr3 = [Double](repeating:
0.0, count:
3)
//[0.0, 0.0, 0.0]
var arr4 = Array(repeating:
3.0, count:
3)
//[3.0, 3.0, 3.0]
var arr: [String] = [
"Alex",
"Brian",
"Dave"]
print(arr.count)
print(arr[0])
8.2数组遍历
// forin方式
for name
in array1{
print(name)
}
// 遍历数组
for i
in 0..<
array2.count{
print(array2[i])
}
//区间遍历
for item
in array2[
0..<
2] {
print("item\(item)")
}
// 同时遍历下标和内容
print(
"=====同时遍历下标和内容=====")
for e
in array2.enumerated(){
print(e)
//offset 下标 element 值
print(
"元组 \(e.offset) \(e.element)")
}
//下标和值同时遍历
for (n, s)
in array2.enumerated() {
print(n, "===", s)
}
// 反序遍历
for a
in array2.reversed(){
print(a)
}
// 遍历下标和数值 反序
for (xxx,ooo)
in array2.enumerated().reversed() {
print(xxx,"==",ooo)
}
8.3数组增删改
// 追加
arr.append(
"ningcol")
// 合并(类型必须一致)
let arr1 = [
"Evi",
"Tank"]
arr +=
arr1
// 修改
arr[
0] =
"Tom"
print(arr)
// 删除
arr.removeFirst()
print(arr)
//根据索引删除
arr.remove(at:
2)
print(arr)
// 删除全部并保留空间
arr.removeAll(keepingCapacity:
true)
print(arr.capacity) //数组容量
/***************************容量*************************/
// 容量每次都会在原来基础上 * 2
print(
"初始容量 \(array3.capacity)")
for i
in 0..<
8{
array3.append(i)
print("--\(array3),容量:\(array3.capacity)")
}
09-字典
01字典定义
//方括号 [] 来创建字典
let dict1 = [
"name":
"lisi",
"age":
"18"]
// 不同类型必须指明为 any
var dict2:[String:Any] = [
"name":
"lisi",
"age":
18]
let array =
[
["name":
"lisi",
"age":
"18"],
["name":
"wangwu",
"age":
8]
]
print(array)
let array1:[[String:Any]] =
[
["name":
"lisi",
"age":
"18"],
["name":
"wangwu",
"age":
8]
]
print(array1)
print(dict2["age"])
02字典增删改
// 增加
dict2[
"sex"] =
"man"
print(dict2)
// 修改(通过key来取值,key不存在就是新增)
dict2[
"name"] =
"zhangsan"
print(dict2)
// 删除(直接给key进行删除)
dict2.removeValue(forKey:
"age")
print(dict2)
03字典遍历
for e
in dict2{
//e 为元组
print(
"字典遍历:\(e) e.key:\(e.key) value:\(e.value)")
}
// key value 可以随意更改
for (key,value)
in dict2{
//e 为元组
print(
"key:\(key), value:\(value)")
}
04字典合并
var dict3:[String:Any] = [
"name":
"zhangsan",
"age":
18,
"sex":
"man"]
let dict4:[String:Any] = [
"name":
"ningcol",
"height":
50]
// 如果key存在修改 不存在会增加
for e
in dict4{
dict3[e.key] =
dict4[e.key]
}
print("合并dict:" + String(format:
"%@", dict3))
10-对象和类
// 创建一个类
class Shape {
var numberOfSides =
0
// 定义 simpleDescription 无参方法,返回值为 String 类型
func simpleDescription() ->
String {
return "A shape with \(numberOfSides) sides."
}
}
// 实例化
var shape =
Shape()
// 赋值
shape.numberOfSides =
7
// 调用方法
var shapeDescription =
shape.simpleDescription()
// 构造函数来初始化类实例
//如 oc :
/*
- (instanceType) initWithName:(NSString *)name;
*/
class NamedShape {
var numberOfSides: Int =
0
var name: String
//自定义构造函数
init(name: String) {
//构造函数内的名字和类属性名字一样,需要使用 self 调用属性
self.name =
name
}
func simpleDescription() ->
String {
return "A shape with \(numberOfSides) sides."
}
}
//let name = NamedShape(name: "name")
//name.simpleDescription()
重写父类方法
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength =
sideLength
super.init(name: name)
numberOfSides =
4
}
func area() ->
Double {
return sideLength *
sideLength
}
// 使用 override
override func simpleDescription() ->
String {
return "A square with sides of length \(sideLength)."
} }
let test = Square(sideLength:
5, name:
"my test square")
test.area()
test.simpleDescription()
01-if let 语句
/*
可选类型在每次访问的时候都会提取并检测它的值是否存在,但有时候根据程序结构可以推断可选量在首次赋值后必然存在值,这时候就不需要每次验证值是否存在了,我们可以使用!进行强制隐式解包来获取它的值,或者使用 if let 语句隐式解包
*/
//强制隐式解包
let possibleString: String? =
"An optional string"
print(possibleString!)
//解包,确定 possibleString 值一定存在,不需要验证
//隐式解包
if let value =
possibleString {
let stringValue =
value
}
02-guard 语句
//grard 语句只会执行一个代码块
//guard 语句判断其后表达式的布尔值为 false 时才会执行之后的代码块里的代码,若为 true, 则跳过整个 guard 语句
//guard 函数只能用在函数里面
func checkLogin(person: [String : String]) {
//检查账号密码,如果用户名为空,则不能登录
guard let uname = person[
"uname"]
else {
print("用户为空,不能登录")
return
}
//检查账号密码,如果密码为空,则不能登录
guard let pawd = person[
"pawd"]
else {
print("密码空,不能登录!")
return
}
//账号和密码都存在,方可进登录
print(
"用户名:\(uname) 密码:\(pawd)")
print("登录中请稍后...")
}
03-自定义构造函数
class Person: NSObject {
var name : String?
var age : Int =
0
override init() {
// 在构造函数中,如果没有明确super.init(),那么系统会帮助调用super.init()
// super.init()
print("------")
}
// 自定义构造函数不需要 override
init(name : String, age : Int) {
self.name =
name
self.age =
age
}
// init(dict : [String : AnyObject]) {
// let tempName = dict["name"]
// // tempName是一个AnyObject?,转成String?
// // as? 最终转成的类型是一个可选类型
// // as! 最终转成的类型是一个确定的类型
// name = tempName as? String
//
//
// /*
// let tempAge = dict["age"]
// let tempAge1 = tempAge as? Int
// if tempAge1 != nil {
// age = tempAge1!
// }
// */
//
// if let tempAge = dict["age"] as? Int {
// age = tempAge
// }
// }
//使用 KVC 必须先掉用 super.init()
init(dict : [String : AnyObject]) {
super.init()
setValuesForKeys(dict)
}
override func setValue(_ value: Any?
, forUndefinedKey key: String) {
}
}
//@interface Person : NSObject
//
//- (instanceType)initWithName:(NSString *)name age: (int)age
//- (instanceType)initWithDict:(NSDictionary *)dict;
//
//@end
let p =
Person()
let p1 = Person(name:
"why", age:
18)
print(p1.age)
print(p1.name)
let p2 = Person(dict: [
"name" :
"why" as AnyObject,
"height" :
1.88 as AnyObject,
"age" :
18 as AnyObject])
print(p2.age)
print(p2.name)
11-枚举
枚举定义
enum SomeEumeration {
// 在这里定义枚举
}
//// 定义枚举类型 指定类型
enum RequestType : String {
case GET =
"GET"
case POST =
"POST"
}
以下是地图四个方向的一个例子:
enum MapDirection {
case North
case South
case East
case West
func simpleDescription() ->
String {
switch self {
case .North:
return "North"
case .South:
return "South"
case .East:
return "East"
case .West:
return "West"
default:
return String(
"unknow")
}
}
}
//多个成员值可以出现在同一行上,用逗号隔开:
enum MapDirection1 {
case North,South,East,West
}
//枚举的使用:枚举名称通过点语法获枚举的某一个取值
var directionToHead =
MapDirection.West
//一旦directionToHead 被声明为一个 MapDirection类型,我们可以使用更短的点(.)语法将其设置为另一个 MapDirection 的值
12-属性
/*
1.存储属性
2.计算属性
3.类属性
*/
class Student: NSObject {
// 定义存储属性
var age : Int =
0
var name : String?
var mathScore : Double =
0.0
var chineseScore : Double =
0.0
// 定义计算属性: 通过别的方式计算到结果的属性,称之为计算属性
var averageScore : Double {
return (mathScore + chineseScore) *
0.5
}
// 定义类型属性: 类属性是和整个类相关的属性.而且是通过类名进行访问
/*
两种创建方法
*/
//第一种方法
static var courseCount : Int =
0
//第二中方法
class var newvalue: Int {
return 10
}
/*
// 定义方法,可以返回平均成绩
func getAverageScore() -> Double {
// 在swift开发中,如果使用当前对象的某一个属性,或者调用当前对象的某一个方法时,可以直接使用,不需要加self
return (mathScore + chineseScore) * 0.5
}
*/
}
// 给类属性进行赋值
Student.courseCount =
2
// 创建对象
let stu =
Student()
// 给对象的属性赋值
stu.age =
10
stu.name =
"yz"
stu.mathScore =
78
stu.chineseScore =
59.9
print(stu.age)
if let name =
stu.name {
print(name)
}
let averageScore =
stu.averageScore
//使用类名调用,对象不可以调用
Student.newvalue
Student.courseCount
/********************************************计算属性***************************************/
/*枚举、类、结构体除了拥有存储属性,还可以定义计算属性。
计算属性不直接存储值,而是提供一个getter和一个可选的setter来间接获取、设置其他属性和变量的值。
*/
//便捷setter声明 如果计算属性的setter没有定义表示新值的参数名,则可以用默认值newValue,
//get:用来取值,封装取值的过程
//set:用来设值,封装设值的过程
// 下面定义三个结构体,来描述一个矩形
class Square {
// 正方形的宽度
var width: Double =
0.0
// 正方形的周长
var girth: Double {
get {
// 周长 = 宽度 * 4
return width *
4
}
set {
// 宽度 = 周长 / 4
width = newValue /
4
}
}
}
var s = Square()
//1
s.width =
10//2
print(s.girth)
//3
s.girth =
200//4
print(s.width)
//5
/*
第3行代码:调用girth属性的get,输出结果是40
第4行代码:调用girth属性的set,并且把200传递给newGirth参数
第5行代码:输出结果是50
*/
//只读计算属性 只有getter没有setter的计算属性
//只读计算属性总是返回一个值,可以通过点语法访问,但是不能设置
//只读计算属性可以省略get和花括号
// 一个结构体 ,volume计算体积
struct Cuboid{
var width =
0.0, height =
0.0, depth =
0.0
var volume: Double{
return width * height *
depth
}
}
let newCuboid = Cuboid(width:
3.0, height:
4.0, depth:
5.0)
/*注意
1.因为计算属性的值不是固定的,因此只能用var修饰计算属性,不能用let
2.一个属性不能既是存储属性,又是计算属性
*/
属性的监视器
//属性监视器可以用来监控属性值的变化,每次属性被修改的时候都会被调用,即使新的值和旧的值一样.
//一个属性监视器由 willSet 和 didSet 组成, willSet 在设置新的值之前被调用,新的值作为传参,didSet 在新的值被设置之后调用,会将旧的属性值作为传参.
class Person: NSObject {
// 属性监听器
var name : String?
{
// 属性即将改变时进行监听
willSet {
print(name)
print(newValue)
}
// 属性已经改变时进行监听
didSet {
print(name)
print(oldValue)
}
}
}
let p =
Person()
p.name =
"why"
p.name =
"yz"
13-下标脚本
//下标脚本
//swift 通过索引快速取值的一种语法.例如数组的a[0]就是一个下标脚本,通过索引0 快速取值,我们可以在类,结构体,和枚举中自己定义下标脚本
//下标脚本使用subscript 关键字来定义 通过 get ,set 来定义读,写属性,可以只有 get 只读方法.定义
//set 属性时,传入的参数类型和subscript 函数返回的值必须相同
/**subscript(参数名称1: 数据类型, 参数名称2: 数据类型,...)-> 返回值的数据类型 {
get {
//返回与参数类型一样的值
} set (参数名称){
// 执行相关的赋值操作
}
}
*/
//代码如下:
class Experience {
var age: [Int] = Array(repeating:
0,count:
5)
subscript(index:Int) ->
Int {
get {
return age[index]
}set {
age[index] =
newValue
}
}
}
//可以通过下标脚本来设置获取某一属性的值
var ex =
Experience()
//设置第一个脚标的值为5
ex[
0] =
5
ex[1] =
6
print(ex[0])
print(ex[1])
/**
下标脚本可以和计算属性一样设置为读写或只读,也就是定义下标脚本时不设置 set 方法,上面的代码是读写形式,下面就使用只读的形式实现使用下标访问属性值的功能
*/
class Experience2 {
var age2: [Int] = Array(repeating:
0,count:
5)
subscript(index:Int) ->
Int {
get {
return age2[index]
}
}
}
//这种情况下,我们只能获取属性值,不能对属性设置值.获取属性值的代码如下
var ex2 =
Experience2()
let e0 = ex2[
0]
let e1 = ex2[
1]
print(e0)
print(e1)
/****************************************************
对之前学习的swift 语法又复习了一下,此文转载简书作者:ningcol 链接:http://www.jianshu.com/p/1c25105bba4f 可以去原作者文章中下载 demo,这里我在原作者文章中又补充了一些基础知识.
***************************************************************/
转载于:https://www.cnblogs.com/ningmengcao-ios/p/5949790.html