Swift语法拾遗

指南

指南的撰写尽量参考IDEA的Plugin参考文档

Property Wrapper

属性包装器,如同切面一样,当你需要对数据进行校验,或者将数据存储到数据库时,一般情况下,你需要对每个属性都写一遍代码。
通过Property Wrapper,

如何定义Property Wrapper: 定义一个结构体或类,声明属性wrappedValue

@propertyWrapper
struct TwelveOrLess {
    private var number = 0
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
    }
}

如何使用Property Wrapper:

struct SmallRectangle {
    @TwelveOrLess var height: Int
    @TwelveOrLess var width: Int
}

内部实现:

struct SmallRectangle {
    private var _height = TwelveOrLess()
    private var _width = TwelveOrLess()
    var height: Int {
        get { return _height.wrappedValue }
        set { _height.wrappedValue = newValue }
    }
    var width: Int {
        get { return _width.wrappedValue }
        set { _width.wrappedValue = newValue }
    }
}

包装器可定义自身的init构造函数以及不同的重载形式

属性投影:在@propertyWrapper中可额外定义一个projectValue属性,该属性在外部通过 a.$v访问:

@propertyWrapper
struct SmallNumber {
    private var number = 0
    var projectedValue = false
    var wrappedValue: Int {
        get { return number }
        set {
            if newValue > 12 {
                number = 12
                projectedValue = true
            } else {
                number = newValue
                projectedValue = false
            }
        }
    }
}
struct SomeStructure {
    @SmallNumber var someNumber: Int
}
var someStructure = SomeStructure()

someStructure.someNumber = 4
print(someStructure.$someNumber)
// Prints "false"

someStructure.someNumber = 55
print(someStructure.$someNumber)
// Prints "true"

所谓投影,其实就出值的状态

Access Control 访问控制

https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html

访问控制限制了代码可访问性

可访问级别:

  • 开发和公开:public
  • 内部(默认,如果没有定义):internal或者不定义
  • 文件私有(仅在源文件内部可见): fileprivate
  • 定义域私有(仅在声明的域内可见): private

typealias

https://docs.swift.org/swift-book/ReferenceManual/Declarations.html

类似于c语言的typedef,为复杂的类型定义一个别名

Typealias用在protocol中,还表示这个类型是该协议的实现需要提供的一个别名,在实现中必须提供typealias A = B

/// A modifier that can be applied to a view or other view modifier,
/// producing a different version of the original value.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol ViewModifier {

    /// The type of view representing the body of `Self`.
    associatedtype Body : View

    /// Returns the current body of `self`. `content` is a proxy for
    /// the view that will have the modifier represented by `Self`
    /// applied to it.
    func body(content: Self.Content) -> Self.Body

    /// The content view type passed to `body()`.
    typealias Content
}

类型:Self和Type以及其他

https://docs.swift.org/swift-book/ReferenceManual/Types.html
Swift中有两种类型: 命名的类型和组合类型

命名的类型就是包括:类(class), 结构体(struct),枚举, 协议,基本类型(数字,字符,字符串)
命名的类型可以使用extension

复合类型是没有命名的类型:函数类型以及元组类型。 (Int,(Int,Int))就是元组类型,但是注意(Int)不是,通常而言,加上括号就能构成新的组合类型。

元组类型: 既有名称,也有类型

var someTuple = (top: 10, bottom: 12)  // someTuple is of type (top: Int, bottom: Int)
someTuple = (top: 4, bottom: 42) // OK: names match
someTuple = (9, 99)              // OK: names are inferred
someTuple = (left: 5, right: 5)  // Error: names don't match

元组类型可用于函数返回多个值

Optional: 有3种声明方式 T? 或 Optional,以及 T!

其中:T!表示的隐式解值,它的含义是:这个类型总是有值(总是不为空,一旦为空,就抛出Runtime异常)

复合协议类型: typealias PQR = P & Q & R

Opaque Type:模糊类型
定义了服从多个协议的类型,但是不必指定底层类型。模糊类型出现在函数的返回值中,语法some Constraint, Constriant可以是class,protocol,协议组合,Any。 类中只有final的method才能返回模糊类型

Meta Type,元类型:类型的类型。类似于java中的元类型是name + .class, Swift中的元类型是 name + .Type, 协议的元类型是 name + .Protocol. 元类型的实例:通过 name + .self来访问,比如String.self, 它返回的是类型(类型是元类型的一个实例),可使用type(…)来获取类型。

Self Type:避免重复键入类型的名称,对于协议而言,Self解析成最终实现类型。

Never

https://swift.gg/2018/08/30/never/
Never类似于其他语言中的,仅仅用于标注不可能的事情,因为Never没有实例话方法,所以不可能构造Never的实例,因此也就没有可能返回Never类型。

如果一个别名定义为Never, typealias Body = Never,则表明这个类型没有值,也就是说协议里面没有实现这个类型。

注意,语言是静态的,只有写代码的人知道代码将会发生什么。就像函数都有返回值,这是语言的假定,但是某些场景中,这个函数就一定不会返回,这就是Never的作用:进一步提示。

guard

guard ... else {...}

如果解析错误,执行else,而不是抛出异常

KeyPath

https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#grammar_key-path-expression

https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#grammar_key-path-string-expression
Swift4新特性
语法:\Type.property.property....

#keyPath(…) 用于objectc

\type name.path 最终编译生成一个KeyPath类型, 实例可接受一个keyPath参数:

struct SomeStructure {
    var someValue: Int
}

let s = SomeStructure(someValue: 12)
let pathToProperty = \SomeStructure.someValue

let value = s[keyPath: pathToProperty]
// value is 12

.self 表示整个实例本身
省略Type时,表示要应用的类型自身

KeyPath泛型参数有两个,一个表示类型,一个表示返回值

@escaping

https://docs.swift.org/swift-book/LanguageGuide/Closures.html -> 搜索@Escaping

逃逸闭包是指:闭包作为一个参数传递给函数,但是在函数返回之后才执行。
比如,需要网络IO函数使用闭包作为回调函数。这种情况下,必须使用@escaping标注闭包,同时,原来的闭包必须明确引用self,而不能直接引用属性名。


protocol

protocol只能作为泛型约束,不能像Java那样作为类型名约束变量类型。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值