//
// main.swift
// Swift_Other
//
// Created by 齐彦坤 on 2017/7/21.
// Copyright © 2017年 KG. All rights reserved.
//
// 2.3 与 3.0 迁移对比 http://www.jianshu.com/p/460b5424942a
import Foundation
// Swift 与 Objective-C 中的 nil
// Swift 使用 nil 代表 <#值缺失#>
// Swift 中 nil与 Objective-C 中的 nil 完全不同, 在 Objective-C 中, nil 代表一个并不次混在的指针对象, 而在 Swift 中并不代表指针而是一个确定的值-------他是一个确定的值, 用于代表"值缺失", 任何 <#可选类型#> 的变量都可以呗赋值为 nil, 如 Int?, Double? 等都可以接受 nil 值.
// can not recieve nil
// Var age: Int = nil
// Int? 类型的才可以接受 nil
// var age: Int? = nil
// var myName : String?
// print(myName ?? "")
var name_prefix = "123456"
var info = name_prefix + "789"
print(info)
name_prefix.removeAll(keepingCapacity: false) // storge and string -- > falses (released) / true (NoReleased)
var diamond : Character = "u{2666}"
var heart : Character = "u{2663}"
var club : Character = "u{2665}"
var spade : Character = "u{2660}"
print("(diamond) (heart) (club) (spade)") // ♦ ♣ ♥ ♠
// -- u{a}
// 7.6 属性观察者
// willSet(newValue): 被观察的属性即将被赋值之前自动调用该方法
// didSet(oldValue): 被观察的属性即将被赋值完成之后自动调用该方法
// 只要程序对非延迟存储的存储属性赋值 --- 即使所赋的值与原值相等, 属性观察者也能监听到
// 属性观察者监听的范围
// 1. 除了延迟属性之外的所有存储属性
// 2. 可以通过重载的方式为继承得到的属性添加属性观察者
// 3. 普通的属性添加属性观察者是没有意义的
/*
// 格式如下
[修饰符] var 存储属性名: 属性类型 [= 初始值]
{
willSet
{
// 属性即将赋值之前的代码
}
didSet
{
// 赋值完成之后的代码
}
}
*/
class Person
{
var name : String = ""
{
willSet
{
if (name as NSString).length > 6 || (name as NSString).length < 2
{
print("no")
}else{
print("yes")
}
}
didSet
{
print("didSetName: (name)")
}
}
}
var p = Person()
p.name = "小黄人"
print("p.name = (p.name)")
// 7.7.6 属性和方法的统一
// 全局函数
func factorial(n:Int) -> Int
{
var result = 1
for idx in 1...n {
result *= idx
}
return result
}
struct SomeStruct
{
// 将一个布闭包函数作为 info 存储属性的初始值
var info:() -> Void = {
print("info 方法")
}
// factorial全局函数作为 fact 存储属性的初始值
static var fact:(Int) -> Int = factorial
}
var sc = SomeStruct()
sc.info()
sc.info = {
print("另外一个闭包")
}
sc.info()
var n = 6
print("(n)的阶乘: (SomeStruct.fact(6))")
// 7.8 下标
/*
subscript(形参列表) -> 下表返回值
{
get
{
// getter 执行部分, 必须有返回值
}
set
{
// setter 部分执行代码, 该部分不一定有返回值
}
}
*/
struct FKRect
{
var x : Int
var y : Int
var width : Int
var height : Int
subscript(idx : Int) -> Int
{
get
{
switch(idx)
{
case 0:
return self.x
case 1:
return self.y
case 2:
return self.width
case 3:
return self.height
default:
print("unSupport type")
return 0
}
}
set
{
switch(idx)
{
case 0:
self.x = newValue
case 1:
self.y = newValue
case 2:
self.width = newValue
case 3:
self.height = newValue
default:
print("unSupport type")
}
}
}
}
var rect = FKRect(x: 20, y: 12, 200, height: 300)
// 通过下表对 rect 的属性赋值
rect[0] = 40
rect[1] = 67
print("rect 的 x 的坐标为: (rect[0]), y 的坐标为 (rect[1])")
// 7.9 可选链
class Company
{
var name = "crazy"
var addr = "home"
init(name : String, addr : String)
{
self.name = name
self.addr = addr
}
}
class Employee
{
var name = " 白骨精"
var title = "销售客服"
var company : Company!
init(name : String, title : String)
{
self.name = name
self.title = title
}
}
class Customer
{
var name = ""
var emp : Employee?
// "_" 取消构造器参数的外部形参名
init(_ name : String)
{
self.name = name
}
}
var c3 = Customer("唐僧")
//print("为(c3.name)服务的公司: (String(describing: c3.emp!.company?.name))") // fatal error: unexpectedly found nil while unwrapping an Optional value
print("为(c3.name)服务的公司: (String(describing: c3.emp?.company?.name))") // fatal error: unexpectedly found nil while unwrapping an Optional value
// 7.11.4 使用闭包后函数为属性设置初始值
// 用于作为存储属性初始值的函数或闭包的返回值类型需要与该属性的类型匹配
struct closurenit
{
var test : Int = {
return 6
}()
}
var ci = closurenit()
print(ci.test)
// 构造器
// 对于值类型, Swift 允许使用 self,init(实参)在自定义在构造器中调用其他重载的构造器, 而且只允许在构造器内部使用self.init(实参)
struct Apple
{
var name : String
var color : String
var weight : String!
init(_ name : String, color : String)
{
self.name = name
self.color = color
}
init(name : String, color : String)
{
// name = "trmp" // 执行 self.init 之前, 不允许对人如何实例睡醒赋值, 也不允许访问任何任何实例属性, 不被允许使用 self. 而一个构造器中只能有一行 self.init(实参)
self.init(name, color: color)
}
init(name : String, color : String, weight : String)
{
self.init(name, color: color) // 构造器代理 --> 在构造器中调用其他构造器来执行构造的过程被称为构造器代理
self.weight = weight
}
}
var ap1 = Apple("红富士", color: "粉红色")
var ap2 = Apple(name: "青苹果", color: "绿色")
var ap3 = Apple(name: "红苹果", color: "红色", weight: "1.0 kg")
// 8.2 类的构造
// 8.2.1 便利构造器
// 定义便利构造器需要早 init 前添加 convenience
// convenience init(形参) { }
// 只有类中才有构造器的概念, 结构体 / 枚举 不支持便利构造器
class Apple_one
{
var name : String!
var weight : Double
// 定义指定构造器
init(name : String, weight : Double) {
self.name = name
self.weight = weight
}
// 定义便利构造器
convenience init(n name : String, w weight : Double)
{
self.init(name : name, weight : weight)
self.name = name
}
}
var APP1 = Apple_one(n : "红富士", w : 1.2)
var APP2 = Apple_one(name : "花牛果", weight : 2.4)
// 指定的构造器总是必须向上代理(调用父类的构造器)
// 指定的构造器总是必须横向代理(调用当前类的其他构造器)
// 安全检查
// 1. 指定构造器必须先初始化当前类定义的实例存储属性, 然后才能向上调用父类构造器
// 2. 指定的构造器必须先向上调用父类构造器, 然后才能对继承得到的属性赋值
// 3. 便利构造器必须先调用一个类的其他构造器, 然后才能对属性赋值.
// 4. 构造器在第一阶段完成之前, 不能调用实例方法, 不能读取实例属性(建议为实例属性都指定初始值)
class Fruit {
var name : String
init(name : String) {
self.name = name
}
}
class Apple_two : Fruit {
var color : String
init(color : String) {
// print(self.color) // 在初始化之前不能使用本类定义的实例存储属性, 编译错误
self.color = color
print(self.color)
self.color = "红色"
// print(super.name) // 不可使用父类定义的实例存储属性
super.init(name: "花牛果")
print(super.name)
super.name = "红富士"
}
convenience init(name: String, color : String) {
// 安全检查 3
// print(self.color)
// super.name = name
self.init(color: "红色")
self.name = name
}
}
var a = Apple_two(color : "绿色")
// 8.2.4 构造器的继承和重写
// 1. 如果子类没有提供任何指定构造器, 那么他将自动继承父类的所有指定构造器及所有便利构造器
// 只要子类的构造器重写了父类的指定的构造器, 则必须在子类构造器前添加 override 修饰符, 即使构造器只是一个便利构造器
// 8.2.5 类与可能失败的构造器
// 条件:
// 1. 该类中的所有实例存储属性都已被赋初始值, (即可有程序指定初始值, 也可有系统隐式分配默认的初始值)
// 2. 所有的构造器都已被执行 (即: return nil 不能位于 self.init(参数)或 super.init(参数)代码之前)
// 可能失败的构造器可以调用同一个类中的普通构造器, 反过来则不能., 但在类中可以调用支持隐式解析可能失败的构造器.
// 在结构体中. 普通的构造器却可以调用同一个结构体中可能失败的构造器
// 8.2.8 之类必须包含的构造器
// required 关键字只是要求所有子类必须包含 required 构造器
// 重新父类的required的指定构造器, 无需添加 override
// 8.3
// is 与 as
// 在使用 is 运算符是需要注意, is 运算符前面操作数的编译时类型要么与后面的类相同, 要么与后面的类具有父子继承关系, 否则会引起编译错误
// as 强制将运算符前面的引用变量转换为后面的类型, 如果转换失败, 程序将导致运行时错误
// as? 可选形式的向下转换. 该运算符也试图将运算符前面的引用变量转换为后面的类型.该运算符总返回已个可选值, 如果抓换成功, 则可选值中包含转换结果; 如果转换失败, 则可选值中包含 nil.
// 推荐用法
/*
if obi is NSString
{
let str : NSString = obj as NSString
}
*/
// Any 和 AnyObject
// AnyObject: 可代表任何类的实例
// Any: 可代表任何类型, 包括 Int, Double 等值类型
// 8.4 嵌套类型
// 在程序外部使用嵌套类型时,则需要添加被嵌套类型前缀.
// 嵌套类型不允许使用 static 或 class 修饰, 嵌套类型没有所谓的 "类型相关的嵌套类型"
class User_nest
{
var holiday: [weekDay]
var location : Point
init(holiday:[weekDay], location:Point) {
self.holiday = holiday
self.location = location
}
struct Point {
var latitude : Double
var longitude : Double
var position : Orientation
// 嵌套枚举
enum Orientation {
case Up, Left, Bottom, Right
}
}
// 定义一个嵌套类型, 枚举 weekDay
enum weekDay {
case Monday, Tuesday, Wednesday, Thursday, Friday, Staturday, Sunday
}
}
var user_nest = User_nest(holiday: [], location: User_nest.Point(latitude:-23.33, longitude: 122.11, position: User_nest.Point.Orientation.Up))
user_nest.holiday.append(User_nest.weekDay.Monday)
// 8.5 扩展
/*
extension String {
// add new function
}
*/
// 扩展不能添加实例存储属性
// 使用扩展添加方法
// 只是添加类型方法时需要在类型方法前添加 static 或 class (为类型添加类型方法天机 class, 为枚举或结构体天机类型方法添加 static)
extension String
{
func substringFromStart(start: Int, toEnd: Int) -> String{
var count = 0
var tmp = ""
for ch in self.characters
{
if count > start {
tmp = "(tmp)(ch)"
}
if count > toEnd - 1 {
break
}
count += 1
}
return tmp
}
static func valueOf(value: Bool) -> String
{
return "(value)"
}
}
var str = "fkit.originsfsfsfsf"
var subStr = str.substringFromStart(start: 2, toEnd: 10)
var length_1 = subStr.lengthOfBytes(using: String.Encoding.utf8)
var length_2 = (subStr as NSString).length
// 8
print(subStr)
print(String.valueOf(value: true))
// 扩展添加构造器
struct Some_Struct_other
{
var name : String
var count : Int
}
extension Some_Struct_other
{
init(name:String)
{
self.name = name
self.count = 0
}
init(count : Int) {
self.name = ""
self.count = count
}
}
var sc1 = Some_Struct_other(name: "fsfsf", count: 5)
var sc2 = Some_Struct_other(name: "adad")
var sc3 = Some_Struct_other(count: 23)
// 使用扩扩展添加嵌套类型
extension String
{
enum Suit : String {
case Diamond = "方"
case Club = "梅花"
case Heart = "红桃"
case Spade = "黑桃"
}
static func judgeSuit(s: String) -> Suit?
{
switch s {
case "方":
return .Diamond
case "梅花":
return .Club
case "红桃":
return .Heart
case "黑桃":
return .Spade
default:
return nil
}
}
}
var S_1: String.Suit? = String.judgeSuit(s: "方")
var S_2: String.Suit? = String.judgeSuit(s: "J")
print(S_1?.rawValue ?? "nil")
print(S_2 ?? "nil")
// 输出结果
// 方
// nil
// 8.6 协议
// class ; 该关键字可有可无. 如果使用 class 关键字,则说明要求定义类型属性, 否则说明要求定义实例属性. 吃出不可用 ststic 代替 class
protocol Storkable
{
var storkeWidth : Double{ get set }
}
protocol Fullable {
var fullcolor : Color? { get set }
}
enum Color {
case Red, Green, Blue, Yellow, Cyan
}
protocol HasArea : Fullable, Storkable {
var area : Double {get}
}
protocol Mathable {
static var pi : Double {get}
static var e : Double {get}
}
struct Rect : HasArea, Mathable {
var width : Double
var height :Double
init(width : Double, height : Double) {
self.width = width
self.height = height
}
var fullcolor: Color?
var storkeWidth: Double = 0.0
var area: Double
{
get
{
return width * height
}
}
static var pi: Double = 3.1415926
static var e: Double = 2.7118
}
class Circle : HasArea, Mathable
{
var radius : Double
init(radius : Double)
{
self.radius = radius
}
var fullcolor: Color?
var storkeWidth: Double = 0.0
var area: Double
{
get
{
return Circle.pi * radius * radius
}
}
static var pi: Double = 3.1415926
static var e: Double = 2.7118
}
var rect_ = Rect( 4.5, height: 4.0)
print(rect_.area)
rect_.fullcolor = Color.Red
rect_.storkeWidth = 1.0
print(rect_.fullcolor ?? Color.Red, rect_.storkeWidth)
var circle = Circle(radius: 2.0)
circle.fullcolor = Color.Green
circle.storkeWidth = 0.5
print(circle.fullcolor ?? Color.Green, circle.storkeWidth)
// 协议指定的方法要求
protocol Eatable
{
// 实例方法
func taste()
// 类方法
static func test (masgs : String...)
}
struct Pie : Eatable
{
var weight : String
func taste() {
print("(weight) 饼干吃起来可口可脆")
}
// 结构体使用 static 修饰类型方法
static func test(masgs: String...) {
print("implement test method")
for msg in masgs {
print("(msg)")
}
}
}
class Apple_fruit : Eatable
{
var name : String
init(name: String) {
self.name = name
}
func taste() {
print("(name) 水分充分, 有营养")
}
// 类使用 class 修饰类型方法
class func test(masgs: String...) {
print("implement test method")
for msg in masgs {
print("(msg)")
}
}
}
Pie.test(masgs: "1", "2", "3")
var pie = Pie(weight: "3.4")
pie.taste()
Apple_fruit.test(masgs: "apple_1", "apple_2", "apple_3")
var apple_fruit = Apple_fruit(name: "红富士")
apple_fruit.taste()
// 8.6.4 协议指定的可变方法要求
// "枚举 / 结构体" 中可变方法用 mutating 修饰, 而类中的可变方法则不加 mutating 修饰
// 8.6.5 协议指定的下表要求
protocol Mathable_one
{
subscript(idx : Int) -> Int {get}
subscript(a:Int, b:Int) -> Int {get}
}
struct /*(class)*/ Linear_Struct : Mathable_one
{
var factor: Int
subscript(idx: Int) -> Int
{
get {
return factor * idx
}
set {
print("Linear_Struct 下表赋值")
}
}
subscript(a: Int, b: Int) -> Int {
return factor * a + b
}
}
var line = Linear_Struct(factor: 5)
print(line[4])
print(line[4, 6])
// 协议指定的构造器要求
// 使用类实现协议, 并实现协议中的构造器方法时,必须使用 required 修饰该构造器, 除非该类使用的 final 修饰, 吃屎可以省略 , 也可以省略
// 重重写父类额方法时, 必须同时使用 required override 修饰
// 只有类中实现协议构造器是才有此要求, 而枚举 / 结钩体中无此要求
// 协议的扩展
protocol Emptyable
{
var isEmpty : Bool { get }
}
extension String : Emptyable {}
func foo(arg: Emptyable) {
print("arg 是否为空, (arg.isEmpty)")
}
foo(arg: "fkfkfk")
foo(arg: "")
// 8.6.10 为类协议
protocol Moveable : class
{
func move()
}
class Car : Moveable {
func move() {
print("car is run....")
}
}
// 为类协议不支持结构体
//struct Car_one : Moveable {
// func move() {
// // ....
// }
//}
// 输出实例与 CustomStringConvertible 协议 (Printable 被废弃了)
class Person_one : CustomStringConvertible
{
var name : String
var age : Int
init(name: String, age : Int) {
self.name = name
self.age = age
}
var description: String {
return "(self.name), (self.age)"
}
var debugDescription: String {
return "(self.name), (self.age)"
}
}
var person_one = Person_one(name: "sunwukong", age: 1333)
print(person_one)
print(person_one.description)
print(person_one.debugDescription)
//sunwukong, 1333
//sunwukong, 1333
//sunwukong, 1333
// 8.8.2 循环引用
class Studdent
{
var name : String
var age : Int
// 使用可选属性关联的 Coach 实例
var coach: Coach?
init(name : String, age : Int) {
self.name = name
self.age = age
}
deinit {
print("(self.name) deinit")
}
}
class Coach
{
var name :String
var skill : String
// 使用可选属性关联的 Student 实例,
// var student : Studdent? // 强引用
weak var student : Studdent? // 弱引用 // ①
// unowned let student : Studdent // 弱引用 // ②
init(name: String, skill : String) {
self.name = name
self.skill = skill
}
deinit {
print("(self.name) coach deinit")
}
}
var stu: Studdent? = Studdent(name: "sunwukong", age: 13313)
var coach:Coach? = Coach(name: "tangshng", skill: "44444")
stu?.coach = coach
coach?.student = stu
stu = nil
coach = nil
// 8.8.4 闭包的弱引用
class Studdent_func
{
var name : String
var age : Int
lazy var stuInfo:() ->String = {
// [weak | unowned] 解决闭包的强引用
[weak self] in
"(self!.name), (self!.age)"
}
init(name : String, age : Int) {
self.name = name
self.age = age
}
deinit {
print("(self.name) deinit")
}
}
var stu_func : Studdent_func? = Studdent_func(name: "bajie", age: 500)
var info__stu: (() -> String)? = stu_func!.stuInfo
stu_func = nil
info__stu = nil
// 第 9 章 泛型 (函数 / 结构体 / 类)
// 定义泛型函数
func copyArray <T> (src:[T], dest:inout [T])
{
for element in src {
dest.append(element)
}
}
var arr = [28, 2]
copyArray(src: [12, 5], dest: &arr)
print(arr) // [28, 2, 12, 5]
var strArr = ["android", "iOS", "JAVA"]
copyArray(src: ["C", "C#"], dest: &strArr)
print(strArr) // ["android", "iOS", "JAVA", "C", "C#"]
// 泛型类型
struct FK_Rect <T>
{
var x : T
var y : T
var width : T
var height : T
var poston : (T, T){
return (self.x, self.y)
}
}
let rect_fk = FK_Rect(x: 1.2, y: 2.3, 8.4, height: 7.8)
let (x, y) = rect_fk.poston
print("rect de 位置 (x), (y)")
let rect_fk_2 = FK_Rect(x: 2, y: 3, 4, height: 5)
let (left, top) = rect_fk_2.poston
print("rect de 位置 (left), (top)")
class Apple_other<T>
{
var info : T
init(info:T) {
self.info = info
}
}
var A1 = Apple_other<String>(info: "sfffss")
print("(A1.info)")
var A2 = Apple_other<Double>(info: 3.44)
print("(A2.info)")
// 从泛型派生子类
class AAA<E> : Apple_other<String> {
var name :String!
}
// 类型约束
func bubbleSort <T : Comparable> ( array : inout [T]) {
// 参考 9.4
}
// 9.5.1 关联类型
// 9.6 where 句子