Swift学习笔记

Swift和OC的不同

1.类型推断,不需要指定变量的类型,swift相比OC最强大的地方在于编译器,Swift编译器是全类型编译器,在编译的时候就知道了所有的对象的类型,这是OC的动态编译所做不到的,这样做有一个好处,就是类型安全
2.Swift当中不能向nil发送消息
3.泛型 允许向Java那样将数据类型参数化.
4.字符串做了一些增强
5.switch语法做了精简,提供了范围限制

引入的时候没有双引号,也没有尖括号,直接写框架名
import Foundation
//输出函数
//字符串取消前面的@标记
//没有分号,分号是可选写入的
print("Hello, World!")

1.变量和常量的声明

let myGender = "男"//常量
var carName = "BMW"//变量
carName = "Audio"```
Swift中允许使用任何Unicode字符作为变量和常量的名字,包括哪些不在ACSII编码的字符(不过貌似然并卵)

let 李帅 = "呆萌2b"
let 😳 = "呵呵"
let 🐶 = "狗"
print(🐶)
var a = 10
var b = "A"
var c = 100.1
var d = 200.2
var e = c+d
var char = "A"//这样的创建的是字符变量

####2.类型判断
swift中定义变量和常量的时候,不需要标识出变量和常量的类型,系统会自动进行匹配补全,但是也可以进行手动指定

let name = "小超"//这里就会自动推断为String类型,是由后面的字符串推断出来的
let name1 : String = "西门庆"//这个常量就不会进行类型推断,因为已经显示的指定了常量的类型
//swift中(系统原生的)所有的类型都是首字母大写,剩下的小写
var age :Int = 20
var weight : Float = 130
var money : Double = 100000000

不论是变量还是常量,要么赋初值,要么指定类型,要么指定为可选类型,要么指定类型并且赋初值,否则报错

####3.可选类型
在Swift当中对象没有赋初值就没有起始值,没有值的量是不能使用的,会报错和警告,这个时候就需要可选类型,可选类型简单来说就可以理解为,允许为空
将一个变量声明为可选类型?很简单,在最后面加一个?就可以了

//声明一个可选类型的字符串变量
var sex : String?
print(sex)
sex = "女"
print(sex)
print(sex!)//显示拆包,用!可以将可选类型中的数据拆解出来

//下面的代码因为不能为空又没有进行初始化,所以会报错
//var sex2 : String
//print(sex2)

####4.字符串

//(1).创建空的字符串
var str_empty :String = ""
var str_empty2 :String = String()
//(2).判断字符串是否为空
if str_empty.isEmpty{
print("字符串是空")
}
//(3).字符串拼接
var str1 = "aaa"
var str2 = "bbb"
var str3 = "!!!"
var str4 = str1 + str2 + str3
print(str4)
//(4).字符串中间插入数值
//swift中占位符更改了,使用()来进行变量和常量的取值
print("字符:(str4)\n")
//(5).获取字符串长度
print(str4.characters.count)
//(6).字符串等值判断
if str1 != str2{
print("两个字符串不相等")
}

####5.(隐式类型转换)
swift里面没有隐式类型转换,只有显示类型转换

//强制类型转换语法: Float()
let aa:Int = 3
let bb:Float = 2.3
var cc = Float(aa)+bb

####6.数组的使用
swift中的特点�:1 存储的所有的数据类型必须是同一类型 2 不必非得是对象类型,基本数据类型也可以存储

//数组的创建方式
var nameArray = ["呵呵","阿斯顿","金坷垃"];//首先推断为数组,数组里面元素的类型为字符串
//这种事直接显示指定数组和其元素类型
var nameArray1:Array<String> = ["小明","老王","星池"];
//创建一个空的数组
var array = Array<String>()//推荐用这种
var array1 = Int//创建一个整型的数组

//访问数组
print("数组第一个元素是(nameArray[0])")
//添加元素
nameArray.append("金条")
nameArray.insert("小祥", atIndex: 0)
print(nameArray)
//删除
nameArray.removeAtIndex(0)
print(nameArray)
//修改
nameArray[0] = "小翔子"
print(nameArray)

####7.字典
```
//定义字典
var score:Dictionary<String,Int> = ["小贱":99,"小杰":82,"小随":56]
//定义空的字典
var dic1:Dictionary<String,Int> = [:]
var dic2 = Dictionary<String,Int>()//推荐
//添加键值对
score["小欧"] = 95
//修改某个键值对
score["小贱"] = 59
print(score)
//删除
score.removeValueForKey("小杰")
print(score)
```
####8.元组
元组是将任意类型的任意个数的元素组成一个新的数据类型
```
var status = ("大神32",["18","19","20"],32)
var status1:(className:String,ages:Array,count:Int) = ("大神32",["18","19","20"],32)
//元组数据的访问
//方式1
print(status.0)
//方式2
print(status1.className)
```
元组的建议:元组中的元素过多,用标记名称,元组中的元素较少,种类能够分开,直接使用下标

####9.分支语句
在swift当中,bool类型只有true个false 没有YES和NO

```
let flag = true
if flag == true{
    print("开心")
}else{
    print("不开心")
}
```
switch
```
1.不需要使用break,不会有贯穿现象
let ageOfCat = 10
switch ageOfCat{
case 0:
    print("小包")
case 1:
    print("阿包")
default:
    print("包包")
}
2.支持区间选项
switch ageOfCat{
case 0..<10://半闭区间
    print("哈宝")
case 10...100://闭区间
    print("呢宝")
default:
    print("腰包")
}
3.支持where子句
switch ageOfCat{
case var value where ageOfCat < 10 && ageOfCat > 0:
    value++
    print("baobao")
case var value2 where ageOfCat >= 10 && ageOfCat < 100:
    print("大宝")
default:
    print("hehe")
}
```
####10.循环
```
for循环
for var i = 0; i < 10 ; i++ {
    print("我是第\(i)遍")
}
 let arr = ["🐂","🐴","🐍","🐰","🐲","🐯"]
//遍历数组
for a in arr{
    print(a)
}
//遍历字典
let dict = ["❀":18,"西施":16,"杜十娘":21]
for (key,value) in dict{
    print("\(key)->\(value)")
}
//while
var number = 5;
while number > 0{
    number--
    print(number)
}

repeat {
    print("dasd")
    number--
}while number > -6
```
####11.函数
```
//无参无返回值的函数
func function1() ->Void{
    print("啦啦啦")
}
//无参有返回值的函数
func function2() ->Int{
    return 10
}
//有参无返回值的函数. 参数列表是先写参数名,再写参数类型
func function3(a:Int,b:Double) ->Void{
    
}
//有参有返回值的函数
func function4(a:Int,b:Double) ->Int{
    return a + Int(b)
}
//函数调用的时候需要显示的标明参数名字,但是,一般第一个参数不写,剩下的参数都要标明参数的名字
function4(5, b: 2.0)
//inout参数
//参数默认的是let类型的,但是swift提供了另外一种方式,可以将参数和传入的值进行关联,就是inout
func change(inout value : Int){
    value = 10
}
var number1 = 20
change(&number1)
print(number1)
```
####12枚举
```
enum Season : Int{
    case spring = 10
    case summer
    case autumn
    case winter
}
print(Season.summer.rawValue)
```
####13 结构体
```
struct Rect {
    //声明结构体的变量属性,(存储属性)
    var x : Float
    var y : Float
    var width : Float
    var height :Float
    //声明结构体属性
    static var desription:String?
    //声明结构体的变量属性,(计算属性)
    //计算属性:这个属性专门计算其他属性的值,但其本身并不存储值,一般提供setter,getter方法,在setter,getter方法中实现对其他属性的计算
    var centerX :(Float){
        //setter方法
        set{
            //这里的newValue是系统传递过来的数值,代指就是调用set方法的时候赋予的值
            //如果这个修改的属性是let类型的,那么不能进行修改,会报错
            x = newValue
        }
        //getter方法,这个方法必须要有,否则报错
        get{
            return x+width/2
        }
    }
    var centerY :(Float){
        //get方法是必须的,但是set方法可以省略
        get{
            return y + height/2
        }
    }
    var totalLength:(Float){
        set{
            //计算属性可以对多个属性进行操作
            width = newValue / 4
            height = newValue / 4 
        }
        get{
            //也可以同时返回多个属性计算的结果
            return (width + height) * 2
        }
    }
    //swift里面结构体可以声明方法
    //声明方法,结构体方法不设置返回值
    func frameInfo(){
        print("frame的宽为\(width),高为\(height),周长为\(width*2 + height*2)")
        //属性值的改变只能在计算属性里去写
//        description = "2016年4月8日创建"
//        print(desription)
    }
    //声明结构体方法
    static func info(){
        print("这是一个结构体方法")
        //结构体变量只能在结构体方法里面使用,正常方法不能使用
        desription = "2016年4月8日创建"
    }
}
//初始化结构体
var frame = Rect(x: 100, y: 100, width: 200, height: 200)
//打印frame的数值
print(frame)
frame.x = 300
print(frame)
//计算属性的使用
frame.centerX = 200//这一句代码相当于调用了centerX属性的set方法
print(frame)
print(frame.centerX)//这一句代码相当于调用了CenterX属性的get方法
print(frame.totalLength)
//方法的调用
frame.frameInfo()

Rect.info()
```
####14 类
```
/*
class Person{
    //属性
    var name : String?
    var age : Int?
    //初始化方法,这里的参数列表要和上面的保持一致
    init(name :String, age : Int){
        self.name = name
        self.age = age
    }
}
//1.类的使用
var person = Person(name: "铁锤", age: 18)
//2.属性的使用
print(person.name!)
*/
class Person {
    //1.属性
    //声明对象方法
    var name : String?
    var age :Int?
    //声明类属性
    static var introduce : String?
    //计算属性
    var value : Int{
        //类中计算属性实现的不同
        set(a){
            age = a//set get方法中不能出现self,会造成死循环
        }
        get{
            return age!//这里不要忘记了拆包(去掉括号)
        }
    }
    //方法
    //声明类方法
    //在类中,如果方法使用static修饰,那么表示两个事,1 他是类方法 2.他不能被子类重写
    static func sayHi(){
        print(introduce!)//类属性只能在类方法中使用,正常方法中不能使用
    }
    //在类中,如果方法使用class修饰,那么表示两个事,1 他是类方法 2.他能被子类重写
    class func sayHi1() {
        print(introduce!)
    }
    //声明实例方法
    func sayHi2(){
        print("我是实例方法~~~")
    }
    //自定义初始化方法(构造函数)
    init(name : String ,age : Int){
        self.name = name
        self.age = age
    }
    init(name : String){
        self.name = name
    }
}
//怎么让类继承另一个类
class Student : Person{
    //重写父类的方法
    //子类  重写父类的方法,必须添加override关键字
    override class func sayHi1() {
        print("我是Student类,重写了父类的类方法")
    }
    //重写父类的实例方法
    override func sayHi2() {
        print("我是Student类,重写了父类的实例方法")
    }
}
//类的创建和使用
var person = Person(name: "小海", age: 18)
//调用类的类属性
Person.introduce = "我是Person类"
//调用类方法
Person.sayHi()
Person.sayHi1()
//调用实例方法
person.sayHi2()
//调用实例变量
print(person.name!)
person.name = "小通"
print(person.name!)
//调用计算属性
person.value = 30
print(person.age!)
//关于Student
var student = Student(name: "小2B", age: 23)
//调用实例方法
student.sayHi2()
//调用类方法
Student.sayHi()
Student.sayHi1()

```
####15 值类型和值引用
```
*/
//struct Animal {
//    var name : String
//    var age : Int
//    init(name : String,age : Int){
//        self.name = name
//        self.age = age
//    }
//}
////使用这个方法
////1.创建一个dog变量
//var dog = Animal(name: "旺财", age: 8)
////2.创建另一个dog变量,等于原先的dog变量
//var dog1 = dog//此时dog1的值是从dog变量中拷贝一份出来的,是新的值
////3.改变原先的dog变量
//dog.name = "阿黄"
////4.打印两个变量的值
//print("\(dog.name)--\(dog1.name)")


class Animal {
    var name : String?
    var age : Int?
    init(name : String,age : Int){
        self.name = name
        self.age = age
    }
}
//创建类的对象
var cat = Animal(name: "(>^ω^<)喵", age: 8)
var cat1 = cat
cat.name = "喵喵"
print("\(cat.name!)--\(cat1.name!)")

/**
*  协议(protocol)
*/
//如果协议里面包含可选实现的方法,那么需要添加一个@objc关键字作为标记
@objc protocol marryDelegate{
    //协议里面写的方法都是必须实现的
    func cook()
    func washCloth()
    //协议里面如果方法可选,需要加关键字optional
    optional func HitDouDou()
}

protocol husbandDelegate{
    //挣钱
    func makeMoney()
}
//class man : Person<marryDelegate,husbandDelegate>
//swift规定 类名后面第一个是父类,剩下的都是接受的协议名字
class Man : Person,marryDelegate,husbandDelegate {
    @objc func cook() {
        print("河南烩面")
    }
    @objc func washCloth() {
        print("洗衣机洗去")
    }
    func makeMoney() {
        print("$66666")
    }
}

//看看协议是否好用
var man = Man(name: "小小",age:18)
man.makeMoney()

//类的扩展(Extension)
//1.扩展类遵循的协议中的方法的实现
extension Man{
    @objc func HitDouDou() {
        print("打豆豆")
    }
}
//2.扩展一个类的方法,给某一个类添加一个方法,类似于OC里面的Category
extension Man{
    //添加一个方法
    func joke(){
        print("讲笑话")
    }
}
man.HitDouDou()
man.joke()

```
####16 闭包(Block)
```
*/
//Block 匿名函数
//int(^myBlock)(int a, int b)= ^int (int a, int b) {
//  return a>b?a:b
// }
var MyBlock : ((a : Int,b : Int)->Int)
//功能:求两个数的最大值
//第一种方式
MyBlock = {
    (a : Int, b : Int)->Int in //in 是闭包语法结构的一部分,必不可少,前面指定的是参数列表和返回值等信息
    return a > b ? a : b
}
//第二种方式
MyBlock = {
    a,b in
    return a > b ? a : b
}
//第三种
MyBlock = {
    (a,b)->Int in
    return a > b ? a : b
}
//第四种
MyBlock = {
    a,b in
    a > b ? a : b
}
//第五种 装逼神器
MyBlock = {
    $0 > $1 ? $0 : $1
}

//调用
let max = MyBlock(a: 3, b: 5)
print(max)

```
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容