Swift学习-Enumerate、Structure

1.枚举

1.1枚举定义

//枚举类型可以省略
enum enumName : type?{
    case value1
    case value2
}

定义一个星期枚举

enum DaysOfAWeek{
    case Monday
    case Tuesday
    case Wednesday
}
也可以写为
enum DaysOfAWeek{
    case Monday, Tuesday,Wednesday
}

//枚举值按以下方式指定给变量
var today = DaysOfAWeek.Monday
today = .Tuesday

//与Switch联合使用
switch today {
case .Monday:
    print("Today is Monday")
case .Tuesday:
    print("Today is Tuesday")
case .Wednesday:
    print("Today is Wednesday")
default:
    print("Today is neither Monday nor Tuesday")

}

定义枚举初始值

enum DaysOfAWeek{
    case Sunday
    case Monday
    case Tuesday
    case Wednesday
    init() {
        self = .Sunday
    }
}
var today = DaysOfAWeek()
//此时默认为:Sunday

关联值,枚举允许每个case有一个或更多类型参数

enum ValuesOfDifferentType{
    case Str(String)
    case Inte(Int)
    case Numb(Double)
    case LatLng(Double,Double)
    case Boo(Bool)
    init(){
        self = .Str("Hello World")
    }
}

此时可以结合switch,根据case中的入参,返回不同的值

enum ValuesOfDifferentType{
    case Str(String)
    case Inte(Int)
    case Numb(Double)
    case LatLng(Double,Double)
    case Boo(Bool)
    init(){
        self = .Str("Hello World")
    }
}

在moya网络请求封装中就使用到了;使用moya封装网络请求时,需要定义一个枚举,遵循TargetType;枚举中定义需要访问的接口类型,大多根据接口功能定义case;因为我们项目请求接口定义比较标准,大都使用一个入参格式,所以我没有将全部的接口展示,只区分了上传、下载以及post请求。代码片段如下

public enum SWNetworkAPI{
    case requestWithVersion(params: [String: Any])//请求
    case requestUploadImage(params: [String: Any],urlParams:[String : Any])//上传图片
    case requestUploadImages(params: [UIImage],urlParams:[String : Any])//批量上传图片
}

//通过扩展遵循协议 : 当一个类型已经符合了某个协议中的所有要求,却还没有声明遵循该协议时,可以通过空扩展体的扩展来遵循该协议:
//从现在起,SWNetworkAPI的实例可以作为 TargetType 类型使用:
extension SWNetworkAPI : TargetType {
  //服务器地址
    public var baseURL: URL {
        switch self {
        case .requestWithVersion:
            return URL.init(string: TSP_BASE_URL)!
        case .requestUploadImage:
            return URL.init(string: TSP_BASE_URL)!
        case .requestUploadImages:
            return URL.init(string: TSP_BASE_URL)!
        }
     }
    //各个请求的具体路径
     public var path: String {
        switch self {
        case .requestWithVersion:
            return TSP_POST_PATH
        case .requestUploadImage:
            return TSP_UPLOAD_IMAGE
        case .requestUploadImages:
            return TSP_UPLOAD_IMAGES
        }
    }
    
    //请求类型
    public var method: Moya.Method {
        switch self {
        case .requestWithVersion:
            return .post
        case .requestUploadImage:
            return .post
        case .requestUploadImages:
            return .post
        }
    }

    //请求任务事件(带上参数)
    public var task: Task {
        switch self {
        case .requestWithVersion(let params):
		//根据入参,生成task,返回task
            return .requestParameters(parameters: params, encoding: JSONEncoding.default)
        case .requestUploadImage(let params,let urlParams):
        case .requestUploadImages(let params,let urlParams):
            return .uploadCompositeMultipart(formDataArray as! [Moya.MultipartFormData], urlParameters: urlParams)
        }
    }
    //定义请求头
    public var headers: [String : String]? {
        switch self {
        case .requestWithVersion:
            return ["Content-type" : "application/json;charset=utf-8;","Accept-Language":"zh-CN"]
        case .requestUploadImage:
            return ["Content-Type" : "Multipart/form-data","Accept": "application/json;charset=utf-8"]
        case .requestUploadImages:
            return ["Content-Type" : "Multipart/form-data","Accept": "application/json;charset=utf-8"]

        }
    }
}

言归正传!!!

定义枚举类型,枚举可以向变量和常量一样定义一个类型;下面定义的就是一个String类型的枚举。

*注意:
1.枚举类型的原始值,必须是字面量
2.只有定义了枚举类型,才可以给case赋值
3.如果没有定义枚举类型

enum DaysOfAWeek : String{
    case Sunday = "Today is Sunday"
    case Monday = "Today is Monday"
    case Tuesday = "Today is Tuesday"
    case Wednesday
}

然后可以根据rawValue获取,枚举的具体值

var today = DaysOfAWeek.Sunday.rawValue//打印结果:Today is Sunday
today = DaysOfAWeek.Wednesday.rawValue//打印结果:Wednesday

也可以通过rawValue检索枚举中的case值。

var possibleDay = DaysOfAWeek(rawValue: "Today is Monday")
print(possibleDay ?? "Day doesn't exist")
//打印结果:Monday
possibleDay = DaysOfAWeek(rawValue: "Thursday")
print(possibleDay ?? "Day doesn't exist")
//打印结果:Day doesn't exis

自动设置原始值
枚举可以自动设置case原始值,当枚举类型为Int、Double、float

//例子1
enum Numbers : Int{
    case caseOne = 100, caseTwo
    case caseThree
}
var num = Numbers.caseOne.rawValue//打印结果:100
num = Numbers.caseTwo.rawValue//打印结果:101
num = Numbers.caseThree.rawValue//打印结果:102
//例子2
enum NumbersO : Int{
    case caseOne
    case caseTwo = 2
    case caseThree
}
var numO = NumbersO.caseOne.rawValue//打印结果:0
numO = NumbersO.caseTwo.rawValue//打印结果:2
numO = NumbersO.caseThree.rawValue//打印结果:3
//例子3
enum NumbersT : Int{
    case caseOne = 100, caseTwo = 2
    case caseThree
}
var numT = NumbersT.caseOne.rawValue//打印结果:100
numT = NumbersT.caseTwo.rawValue//打印结果:2
numT = NumbersT.caseThree.rawValue//打印结果:3

将枚举转换成字符串

enum DaysOfAWeek : String{
    case Sunday
    case Monday
    case Tuesday
    case Wednesday
    func day()->String{
        return self.rawValue
    }
}
var str = DaysOfAWeek.Sunday.day()
print(str)//打印结果:Sunday

2.Struct

struct 定义

struct Name{
    //properities here
}

定义一个矩形

struct Rectangle{
    var width = 0
    var height = 0
}

要访问或修改结构体的属性我们用点操作符

var rectangle = Rectangle()
print(rectangle.width)//打印结果:0
print(rectangle.height)//打印结果:0

rectangle.width = 10
rectangle.height = 10

如果初始化的结构,是常量,结构体中的属性值不能修改

let rectangleConstant = Rectangle()
rectangleConstant.height = 20//报错
rectangleConstant.width = 20//报错

struct Circle{
    let radius = 0
}

var circle = Circle()
circle.radius = 10//报错

结构体中定义函数

struct Rectangle {
    var width = 0
    var height = 0
    //手动输入宽高,获取面积
    func area(width :Int, height: Int) -> String
    {
         return "Area is  \(width*height)"
    }
    //根据结构体内部参数值,获取面积
    func area() -> String{
        return "Return area is \(self.width * self.height)"
    }
    //修改参数
    mutating func printModifiedWidth() -> String
    {

        width = width*2
        return "Modified width is \(width)"
    }
    //自定义初始化方法
    init(width: Int, height: Int) {
        self.width = width*2
        self.height = height*2
    }
    //初始化委托
    init(width: Int){
        self.init(width: width,height: width)
    }
    //默认声明,不然空初始化会报错
    init(){
        self.init(width: 0,height: 0)
    }
    //静态函数
    static func printString() -> String
    {

    return "Hello how you're doing"
    }
}
//使用如下所示的结构实例调用函数
var rectangle = Rectangle()
rectangle.width = 10
rectangle.height = 10
rectangle.area(width:rectangle.width,height:rectangle.height)
rectangle.area()

//如果要在函数中修改属性值,我们需要用关键字mutating来标记函数,然后给属性重新赋值
//结构体中的属性不能在内部函数中修改,将函数声明为内部突变函数,将允许我们改变结构体中的属性
rectangle.printModifiedWidth()
print(rectangle.width)//打印结果:20

//结构体初始化有两种形式,
//1.空的初始化()
var rectangleInitial = Rectangle()
//2.也可以是在括号内列出结构属性的成员初始值设定项,以便可以为它们指定新值,但是麻烦再需要给每个属性都赋值
var rectangleInitialMemberWise = Rectangle(width:10,height:10)

//我们也可以在结构体内部自定义初始化方法
var rectangleCustom = Rectangle(width: 10, height: 10)
print(rectangleCustom.width) //prints 20
print(rectangleCustom.height) //prints 20

var square = Rectangle.init(width:20)
print(square.width) //prints 40
print(square.height) //prints 40

//结构体内部的静态函数可以在不创建结构实例的情况下调用
Rectangle.printString()//打印结果:Hello how you're doing

可以使用以下语法动态计算属性
get:当属性值改变时,自动改变area

struct Rectangle {
    var width = 0
    var height = 0
    
    var area: Int {
        get {//计算结果
            return width*height
        }
        set {//初始值
            area = 0
        }
    }
}
var rectangle = Rectangle()
print(rectangle.area) //prints 0
rectangle.width = 20
rectangle.height = 20
print(rectangle.area) //prints 400

Swift结构是通过值传递的,而不是通过引用传递的

var rect = rectangle
rect.width = 30
print(rectangle.width) //prints 20 and NOT 30
上一篇:《JavaScript 面向对象精要》第 5 章 继承


下一篇:492. Construct the Rectangle - LeetCode