编程技术记录

世界你好!

使用SwiftUI时,经常会遇到@ViewBuilder,代码看起来很简洁,背后确实复杂的语法规则。

本文涉及三点:

  • @resultBuilder
  • 可变参数
  • 闭包以及尾随闭包

我们可以自己定义一个类似@ViewBuilder的注解,本文将实现一个自定义的字符串拼接的注解。

首先 用 @resultBuilder修饰的 struct符号需要实现静态buildBlock方法

@resultBuilder public struct TestStringBuilder {
    public static func buildBlock( s1 : String ,s2 : String) -> String {
        return s1 + s2
    }
}

然后定义一个函数,只有一个闭包参数,参数使用@TestStringBuilder修饰

func  test_string_builder(@TestStringBuilder strs_join: () -> String ) {
    print(strs_join())
}

现在可以给test_string_builder传入闭包参数了

test_string_builder( strs_join :{
    "a"
    "b"
})

//将打印字符串 “ab”

该尾随闭包出场了,它是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用

test_string_builder(){
    "a"
    "b"
}

//将打印字符串 “ab”

如果函数只需要闭包表达式一个参数,当您使用尾随闭包时,可以把()省略掉

test_string_builder{
    "a"
    "b"
}

//将打印字符串 “ab”

现在是不是有点像@ViewBuilder的用法了?最后是可变参数,修改下buildBlock定义,以支持可变参数

@resultBuilder public struct TestStringBuilder {
    public static func buildBlock(_ strs: String...) -> String {
        var ret = ""
        for s in strs {
            ret = ret + s
        }
        return ret
    }
}

最终test_string_builder的用法

test_string_builder {
    "a"
    "b"
    "c"
    "d"
}

//将打印字符串 “abcd”

@ViewBuilder的原理和上面类似。

吐槽下,编译器做了很多事,以至于让人习惯语法糖后忘记了该有的本来面目。

发表回复

© Beli. All Rights Reserved.