Swift笔记 - 14.字面量、模式、条件编译、日志、API可用性、程序入口、Swift与OC互调

Swift笔记 - 14.字面量、模式、条件编译、日志、API可用性、程序入口、Swift与OC互调

字面量

var age = 10
var isRed = false
var name = "Jack"
public typealias IntegerLiteralType = Int
public typealias FloatLiteralType = Double
public typealias BooleanLiteralType = Bool
public typealias StringLiteralType = String

//可以通过typealias修改字面量的默认类型
typealias FloatLiteralType = Float
typealias IntegerLiteralType = UInt8
var age = 10 // UInt8
var height = 1.68 // Float

字面量协议

var b: Bool = false // ExpressibleByBooleanLiteral
var i: Int = 10 // ExpressibleByIntegerLiteral
var f0: Float = 10 // ExpressibleByIntegerLiteral
var f1: Float = 10.0 // ExpressibleByFloatLiteral
var d0: Double = 10 // ExpressibleByIntegerLiteral
var d1: Double = 10.0 // ExpressibleByFloatLiteral
var s: String = "jack" // ExpressibleByStringLiteral
var arr: Array = [1, 2, 3] // ExpressibleByArrayLiteral
var set: Set = [1, 2, 3] // ExpressibleByArrayLiteral
var dict: Dictionary = ["jack" : 60] // ExpressibleByDictionaryLiteral
var o: Optional<Int> = nil // ExpressibleByNilLiteral

字面量协议的应用

extension Int : ExpressibleByBooleanLiteral {
    public init (booleanLiteral value: Bool) { self = value ? 1 : 0 }
}
var num: Int = true
print(num) // 1
class Student : ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral, ExpressibleByStringLiteral, CustomStringConvertible {
    var name: String =
    var score: Double = 0
    required init(floatLiteral value: Double) { self.score = value }
    required init (integerLiteral value: Int) { self.score = Double(value) }
    required init(stringLiteral value: String) { self.name = value }
    required init(unicodeScalarLiteral value: String) { self.name = value }
    required init(extendedGraphemeClusterLiteral value: String) { self.name = value }
    var description: String { "name=\(name), score=\(score)" }
}
var stu: Student = 90
print(stu) // name=, score=90.0
stu = 98.5
print(stu) // name=, score=98.5
stu = "Jack"
print(stu) // name=Jack, score=0.0
struct Point {
    var X = 0.0, y = 0.0
}
extension Point : ExpressibleByArrayLiteral, ExpressibleByDictionaryLiteral {
    init (arrayLiteral elements: Double...) {
        guard elements.count> 0 else { return }
        self.x = elements[0]
        guard elements.count > 1 else { return }
        self.y = elements[1]
    }
    init(dictionaryLiteral elements: (String, Double)...) {
        for (k, v) in elements {
            if k == "x" { self.x = v }
            else if k == "y" { self.y = v }
        }
    }
}

var p: Point = [10.5, 20.5]
print(p) // Point (x: 10.5, y: 20.5)
p = ["x' : 11, "y" : 22]
print(p) // Point(x: 11.0, y: 22.0)

Swift 里的模式

通配符模式

enum Life {
    case human (name: String, age: Int?)
    case animal(name: String, age: Int?)
}

func check( life: Life)
    switch life {
    case .human(let name, _):
        print ("human", name)
    case .animal(let name, ?):  //age非空才匹配
        print ("animal", name)
    default:
        print ("other")
    }
}

check(.human(name: "Rose", age: 20)) // human Rose
check(.human(name: "Jack", age: nil)) // human Jack
check(.animal(name: "Dog", age: 5)) // animal Dog
check(.animal(name:"Cat", age: nil)) // other


var num: Int? = 10
switch num {
case let v?:
    print(v)
case nil:
    print("nil")
}

// output:
// false
// Program ended with exit code:

标识符模式

var age = 10
let name = "jack"
let point = (3, 2)
switch point {
case let (x, y) :
    print("The point is at (\(x), \(y)).")
}
let points = [(0, 0), (1, 0), (2, 0)]
for (x, _) in points {
    print(x)
}

let name: String? = "jack"
let age = 18
let info: Any = [1, 2]
switch (name, age, info) {
case (?, _, _ as String):
    print ("case")
default:
    print ("default")
}
// default

var scores = ["jack" : 98, "rose" : 100, "kate" : 86]
for (name, score) in scores {
    print(name, score)
}
let age = 2
//原来的写法
if age >= 0 && age <= 9 {
    print("[0, 9]")
}
// 枚举用例模式
if case 0...9 = age {
    print ("[0, 9]")
}
guard case 0...9 = age else { return }
print ("[0, 9]")

switch age {
case 0...9: print("[0, 9]")
default: break
}

let ages: (Int?] = [2, 3, nil, 5]
for case nil in ages {
    print("有nil值")
    break
} // 有nil值

let points = [(1, 0), (2, 1), (3, 0)]
for case let (x, 0) in points {
    print(x)
} // 1 3
let age: Int? = 42
if case .some (let x) = age { print(x) }
if case let x? = age { print(x) }

let ages: [Int?] = [nil, 2, 3, nil, 5]
for case let age? in ages {
    print (age)
} // 2 3 5

let ages: [Int?] = [nil, 2, 3, nil, 5]
for item in ages {
    if let age = item {
        print (age)
    }
//跟上面的for,效果是等价的

func check(_ num: Int?) {
switch num {
    case 2?: print("2")
    case 4?: print("4")
    case 6?: print("6")
    case _?: print("other")
    case _: print ("nil")
    }
}
check(4) // 4
check(8) // other
check(nil) // nil

以下两种写法等价:

var age: Int? = 10
switch age {
case let x?:
    print(x)
case nil:
    print ("nil")
}

switch age {
case .some(let x):
    print(x)
case .none:
    print("nil")
}
let num: Any = 6
switch num {
case is Int:
    //编译器依然认为nlm是Any类型
    print ("is Int", num)
//case let n as Int:
//    print ("as Int", n + 1)
default:
    break
}

class Animal ( func eat() { print(type(of: self), "eat") }
class Dog : Animal { func run() { print(type(of: self), "run")
class Cat : Animal { func jump() { print (type(of: self), "jump") }
func check( animal: Animal) {
    switch animal (
    case let dog as Dog:
        dog.eat()
        dog.run()
    case is Cat:   //is只是判斷没有转换
        animal.eat()  //只能调Animal的eat
    default: break
    }
}
// Dog eat
// Dog run
check(Dog())
// Cat eat
check(Cat0))
let point = (1, 2)
switch point {
case (0, 0):
    print("(0, 0) is at the origin.")
case (-2...2, -2...2):
    print(" (\(point.0), \(point.1)) is near the drigin.")
default:
    print ("The point is at (\(point.0), \(point.1)).")
}
// (1, 2) is near the origin
struct Student {  // 重载 ~= 运算符
var score = 0, name = ""
static func ~= (pattern: Int, value: Student) -> Bool { value.score >= pattern }
static func ~= (pattern: ClosedRange<Int>, value: Student) -> Bool { pattern.contains (value.score) }
static func
~= (pattern: Range<Int>, value: Student) -> Bool { pattern.contains (value.score) }
}

var stu = Student(score: 75, name: "Jack")
switch stu {
case 100: print(">= 100")
case 90: print(">= 90")
case 80..<90: print("[80, 90)")
case 60...79: print("[60, 79]")
case 0: print(">= 0")
default: break
} // [60, 79]

if case 60 = stu {
    print(">= 60")
} // = 60

var info = (Student(score:70, name: "Jack"), "及格")
switch info {
case let (60, text): print(text)
default: break
} //及格
extension String {
    static func ~= (pattern: (String) -> Bool, value: String)
    -> Bool
        pattern(value)
    }
}

func hasPrefix(_ s: String) -> ((String) -> Bool) { ( $0.hasPrefix(s) }
func hasSuffix(_ s: String) -> ((String) -> Bool) { { $0.hasSuffix(s) }

//以上两行 等价于下面的函数
//func hasPrefix(_ prefix: String) -> ((String) -> Bool) {
//    return { (str: String) -> Bool in
//        str.hasPrefix(prefix)
//    }
//}

//var fn = hasPrefix("21")
//print(fn("123455"))

var str = "jack"
switch str {
case hasPrefix("j"), hasSuffix("k"):
    print("以j开头,以k结尾"
default: break
} //以开头,以k结尾
func isEven(_ i: Int) -> Bool { 1 % 2== 0 }
func isOdd(_ i: Int) -> Bool { 1 % 2 != a }
extension Int {
    static func ~=I(pattern: (Int) -> Bool, value: Int) -> Bool (
        pattern(value)
    }
}

var age = 9
switch age {
case isEven:
    print ("偶数")
case isOdd:
    print("奇数")
default:
    print ("其他")
}
prefix operator ~>
prefix operator ~>=
prefix operator ~
prefix operator ~<=
prefix func ~> (_ i: Int) -> ((Int) -> Bool) { { $0 > i } }
prefix func ~>= (_ i: Int) -> ((Int) -> Bool) { { $0 >= i }
prefix func ~ (_ i: Int) -> ((Int) -> Bool) { { $0 < i } }
prefix func ~<= (_ i: Int) -> ((Int) -> Bool) { { $0 <= i } }

var age = 9
switch age {
case ~>=0, ~<=10:
    print("[0, 10]")
case ~>10, ~<20:
    print("(10, 20)")
default: break
} // [0, 101
var data = (10, "Jack")
switch data {
case let (age, _) where age > 10:
    print(data. 1, "age>10")
case let (age, _) where age > 0:
    print(data. 1, "age>0")
default: break
}

var ages = [10, 20, 44, 23, 55]
for age in ages where age > 30 {
    print (age)
} // 44 55

protocol Stackable { associatedtype Element }
protocol Container {
    associatedtype Stack : Stackable where Stack.Element : Equatable
}

func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _ $2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable (
    return false
}
extension Container where Self.Stack.Element : Hashable { }

条件编译

//操作系统:macOS\iOS\tvOS\watchOS\Linux\Android\Windows\FreeBsD
#if os(macOS)  || os(iOS)
/1 CPU架构: i386\x86_64\arm\arm64
#elseif arch(x86 64) || arch(arm64)
//swift版本
#elseif swift(<5) && swift(>=3)
//模拟器
#elseif targetEnvironment(simulator)
//可以导入某模块
#elseif canImport(Foundation)
#else
#endif

打印日志

func log<T>(_ msg: T, 
             file: NSString = #file,
             line: Int = #line,
               fn: String = #function) {
#if DEBUG
let prefix = "\(file. lastPathComponent)_\(line)_\(fn): "
print (prefix, msg)
#endif

系统版本

if #available(iOS 10, macOS 10.12,*) {
//对于i0S平台,只在i0S10及以上版本执行
//对于macOS平台,只在macOS 10.12及以上版本执行
//最后的*表示在其他所有平台都执行

API可用性

@available(iOS 10, macOS 10.15, *)
class Person (

struct Student {
    @available(*, unavailable, renamed: "study")
    func study_() {}
    func study() {}
    
    @available(i0S, deprecated: 11)
    @available(macOS, deprecated: 10.12)
    func run() {}
}

自定义iOS程序入口

// main.swift
// Test iOS
// Created by MJ Lee on 2019/7/22.
// Copyright © 2019 MJ Lee. All rights reserved.

import UIKit
class XXApplication: UIApplication {}

UIApplicationMain(CommandLine.argc,
                  CommandLine.unsafeArgv,
                  NSStringFromClass(XXApplication.self),
                  NSStringFromClass(AppDelegate.self))

Swift调用OC

//C语言
int sum(int a, int b) {
    return a + b;
}

// Swift
@silgen_name("sum") func swift_sum(_ v1: Int32, _ v2: Int32) -> Int32
print(swift_sum(10, 20)) // 30
print(sum(10, 20)) // 30

OC调用Swift

import Foundation
@objcMembers class Car: NSObject (
    var price: Double
    var band: String
    init (price: Double, band: String) {
        self.price = price
        self.band = band
    }
    func run() { print(price, band, "run") }
    static func run() { print("Car run") }
}
extension car {
    @objc(exec:v2: )
    func test() { print(price, band, "test") }
}
@obic(XXCar)
@objcMembers class Car: NSObject
    var price: Double
    @objc(name)
    var band: String
    init(price: Double, band: String) (
    self.price = price
    self.band = band
    }
    @objc(drive)
    func run() { print(price, band, "run") }
    static func run() { print ("Car run") }
}
extension Car {
    @objc(exec:v2: )
    func test() { print (price, band, "test"}
}
XXCar *c = ([XXCar alloc] initWithPrice: 10.5 band: @"BMW"] ;
c.name = @'Bently";
c.price = 108.5;
[c drivel;  // 108.5 Bently run
[c exec: 10 v2:20]; // 108.5 Bently test
[XXCar run]; // Car run

版权所有,转载请注明出处 luowei.github.io.