当前位置: 首页 > news >正文

电子商务网站面临的安全隐患如何制作网页教程

电子商务网站面临的安全隐患,如何制作网页教程,西安搬家公司哪家便宜,手机与电脑网站制作概述 苹果在去年 WWDC 23 中就为 Swift 语言新增了“其利断金”的重要小伙伴 Swift 宏(Swift Macro)。为此,苹果特地用 2 段视频(入门和进阶)颇为隆重的介绍了它。 那么到底 Swift 宏是什么?有什么用&…

在这里插入图片描述

概述

苹果在去年 WWDC 23 中就为 Swift 语言新增了“其利断金”的重要小伙伴 Swift 宏(Swift Macro)。为此,苹果特地用 2 段视频(入门和进阶)颇为隆重的介绍了它。

在这里插入图片描述

那么到底 Swift 宏是什么?有什么用?它和 C/C++ 语言中的宏又有什么异同呢?本系列博文将会尝试为小伙伴们揭开 Swift 宏的神秘面纱。

在本篇博文中,您将学到如下内容:

  • 概述
    • 5.4 完成宏主体
    • 5.5 验证宏展开后的结果
  • 6. 另一个简洁的解决方案
  • 7. 目前 Swift 宏的不足之处
  • 总结

相信学完本系列博文后,Swift Macro 会从大家心中的“阳春白雪”变为“阳阿薤露”,小伙伴们必可以将它们运用的“如臂使指”。

那还等什么呢?Let‘s go!!!😉


5.4 完成宏主体

在完成了 @nilable 宏接口、客户端代码以及宏主体初步结构的搭建之后,现在回到 NilableMacro 结构的定义中,我们现在可以尝试补全 expansion() 方法中所有展开代码了。

不过在撸码之前,我们有必要先来了解一下 expansion() 方法传入实参所扮演的角色。在这个例子中,我们只关心其中的 declaration 参数,它是一个 some DeclSyntaxProtocol 类型:

providingPeersOf declaration: some DeclSyntaxProtocol

在 Xcode 调试控制台中,我们利用 po 命令可以列出它的结构细节:

FunctionDeclSyntax
├─attributes: AttributeListSyntax
│ ╰─[0]: AttributeSyntax
│   ├─atSign: atSign
│   ╰─attributeName: IdentifierTypeSyntax
│     ╰─name: identifier("nilable")
├─modifiers: DeclModifierListSyntax
│ ├─[0]: DeclModifierSyntax
│ │ ╰─name: keyword(SwiftSyntax.Keyword.static)
│ ╰─[1]: DeclModifierSyntax
│   ╰─name: keyword(SwiftSyntax.Keyword.private)
├─funcKeyword: keyword(SwiftSyntax.Keyword.func)
├─name: identifier("test")
├─genericParameterClause: GenericParameterClauseSyntax
│ ├─leftAngle: leftAngle
│ ├─parameters: GenericParameterListSyntax
│ │ ├─[0]: GenericParameterSyntax
│ │ │ ├─attributes: AttributeListSyntax
│ │ │ ├─name: identifier("Root")
│ │ │ ╰─trailingComma: comma
│ │ ╰─[1]: GenericParameterSyntax
│ │   ├─attributes: AttributeListSyntax
│ │   ├─name: identifier("Value")
│ │   ├─colon: colon
│ │   ╰─inheritedType: IdentifierTypeSyntax
│ │     ╰─name: identifier("Comparable")
│ ╰─rightAngle: rightAngle
├─signature: FunctionSignatureSyntax
│ ├─parameterClause: FunctionParameterClauseSyntax
│ │ ├─leftParen: leftParen
│ │ ├─parameters: FunctionParameterListSyntax
│ │ │ ├─[0]: FunctionParameterSyntax
│ │ │ │ ├─attributes: AttributeListSyntax
│ │ │ │ ├─modifiers: DeclModifierListSyntax
│ │ │ │ ├─firstName: identifier("dump")
│ │ │ │ ├─secondName: identifier("a")
│ │ │ │ ├─colon: colon
│ │ │ │ ├─type: IdentifierTypeSyntax
│ │ │ │ │ ├─name: identifier("KeyPath")
│ │ │ │ │ ╰─genericArgumentClause: GenericArgumentClauseSyntax
│ │ │ │ │   ├─leftAngle: leftAngle
│ │ │ │ │   ├─arguments: GenericArgumentListSyntax
│ │ │ │ │   │ ├─[0]: GenericArgumentSyntax
│ │ │ │ │   │ │ ├─argument: IdentifierTypeSyntax
│ │ │ │ │   │ │ │ ╰─name: identifier("Root")
│ │ │ │ │   │ │ ╰─trailingComma: comma
│ │ │ │ │   │ ╰─[1]: GenericArgumentSyntax
│ │ │ │ │   │   ╰─argument: IdentifierTypeSyntax
│ │ │ │ │   │     ╰─name: identifier("Value")
│ │ │ │ │   ╰─rightAngle: rightAngle
│ │ │ │ ╰─trailingComma: comma
│ │ │ ├─[1]: FunctionParameterSyntax
│ │ │ │ ├─attributes: AttributeListSyntax
│ │ │ │ ├─modifiers: DeclModifierListSyntax
│ │ │ │ ├─firstName: identifier("b")
│ │ │ │ ├─colon: colon
│ │ │ │ ├─type: IdentifierTypeSyntax
│ │ │ │ │ ╰─name: identifier("String")
│ │ │ │ ╰─trailingComma: comma
│ │ │ ╰─[2]: FunctionParameterSyntax
│ │ │   ├─attributes: AttributeListSyntax
│ │ │   ├─modifiers: DeclModifierListSyntax
│ │ │   ├─firstName: identifier("c")
│ │ │   ├─colon: colon
│ │ │   ╰─type: IdentifierTypeSyntax
│ │ │     ╰─name: identifier("Int")
│ │ ╰─rightParen: rightParen
│ ├─effectSpecifiers: FunctionEffectSpecifiersSyntax
│ │ ╰─throwsClause: ThrowsClauseSyntax
│ │   ╰─throwsSpecifier: keyword(SwiftSyntax.Keyword.throws)
│ ╰─returnClause: ReturnClauseSyntax
│   ├─arrow: arrow
│   ╰─type: IdentifierTypeSyntax
│     ╰─name: identifier("Bool")
╰─body: CodeBlockSyntax├─leftBrace: leftBrace├─statements: CodeBlockItemListSyntax│ ╰─[0]: CodeBlockItemSyntax│   ╰─item: PrefixOperatorExprSyntax│     ├─operator: prefixOperator("!")│     ╰─expression: MemberAccessExprSyntax│       ├─base: DeclReferenceExprSyntax│       │ ╰─baseName: identifier("b")│       ├─period: period│       ╰─declName: DeclReferenceExprSyntax│         ╰─baseName: identifier("isEmpty")╰─rightBrace: rightBrace

代码看起来很长,似乎有点儿“一望无际”。不过如果我们查看它的 description 属性就会恍然大悟:它其实就是 @nilable 宏修饰方法所对应的语法树。

在这里插入图片描述

所以基本上来说,我们只需要将 declaration 的内容“修剪”为想要的结果即可。对于我们这个例子,就是将 declaration 中第一个 KeyPath 参数中的 Value 变为可选类型 Value?。

下面是我们第一种实现,因为考虑到了“调皮的”用户可能犯的各种错误,所以比较冗长。不过别急,后面我们会给出精简后的方案:

public static func expansion(of node: AttributeSyntax, providingPeersOf declaration: some DeclSyntaxProtocol, in context: some MacroExpansionContext) throws -> [DeclSyntax] {guard let funcDecl = declaration.as(FunctionDeclSyntax.self) else {throw MacroExpansionErrorMessage("必须在方法上使用我哦!")}let funcName = funcDecl.namelet funcModifiers = funcDecl.modifierslet funcGenericParameterClause = funcDecl.genericParameterClauselet funcEffecSpecifier = funcDecl.signature.effectSpecifiers?.description ?? ""let funcReturnClause = funcDecl.signature.returnClause?.description ?? ""let funcBody = funcDecl.bodyguard let funcFirstParamenter = funcDecl.signature.parameterClause.parameters.first else {throw MacroExpansionErrorMessage("方法必须至少要有 1 个参数哦!")}guard let funcFirstParamenterType = funcFirstParamenter.type.as(IdentifierTypeSyntax.self) else {throw MacroExpansionErrorMessage("方法参数格式错误哦!")}guard funcFirstParamenterType.name.description == "KeyPath" else {throw MacroExpansionErrorMessage("方法的第一个参数必须是 KeyPath 类型哦!")}guard let secondArgment = funcFirstParamenterType.genericArgumentClause?.arguments.last, secondArgment.argument.as(OptionalTypeSyntax.self) == nil else {throw MacroExpansionErrorMessage("方法 KeyPath 参数中的 Value 不是 Optional 类型哦!")}let firstName = funcFirstParamenter.firstName.descriptionvar firstArg = if let secondName = funcFirstParamenter.secondName?.description {"\(firstName)\(secondName): "} else {"\(firstName): "}let rootName = funcFirstParamenterType.genericArgumentClause!.arguments.first!.argument.as(IdentifierTypeSyntax.self)!.name.descriptionlet valueName = secondArgment.argument.as(IdentifierTypeSyntax.self)!.descriptionfirstArg += "KeyPath<\(rootName), \(valueName)?>"let parameters = funcDecl.signature.parameterClause.parametersvar otherParametersDesc = ""if parameters.count > 1 {for parameter in parameters.dropFirst() {otherParametersDesc += "\(parameter.description)"}}let nilFuncDecl = try FunctionDeclSyntax("\(funcModifiers)func \(funcName)\(funcGenericParameterClause)(\(raw: firstArg), \(raw: otherParametersDesc)) \(raw: funcEffecSpecifier)\(raw: funcReturnClause) \(funcBody)")return [.init(nilFuncDecl)]
}

在上面的代码中,我们做了这样几件事:

  • 为用户在构造宏所修饰的表达式时可能犯的各种错误(比如用户在属性而不是方法上应用 @nilable 宏)提供贴心的提示;
  • 确定 KeyPath 中 Value 的名称;
  • 考虑到 KeyPath 参数可能出现的名称前缀;
  • 确定方法签名中的其它信息(比如其它参数类型和返回类型);
  • 考虑到方法本身可能存在一些 modifier 和 effectSpecifiers 修饰器(比如 static、private、throws 等);

5.5 验证宏展开后的结果

回到 main.swift 源代码文件中,在选中 @nilable 宏关键字后将其展开,如果不出意外我们应该可以正确创建 sortItemsBy 排序方法的 KeyPath 可选 Value 版本(Value?):

在这里插入图片描述

这意味着,下面这些代码都可以顺利编译通过了:

let itemsByName = try! model.sortItemsBy(keyPath: \.name)
let itmesByNickname = try! model.sortItemsBy(keyPath: \.nickname)

棒棒哒!成就感爆棚的小伙伴们赶快给自已一个大大的赞吧!👍🏻


其实验证 Swift 宏展开结果最好的方法是使用单元测试,但由于目前宏单元测试略显“呆滞和笨拙”,所以暂时略去不表。


6. 另一个简洁的解决方案

虽然我们解决了问题,但上述实现实在是有点“臃肿不堪”。

让我们马上再做一次头脑风暴:我们实际只是想修改 sortItemsBy() 方法 KeyPath 形参中的 Value,如果只考虑几种可能出现的错误,仅需一个简单的字符串内容替换操作即可大功告成!

下面是我们 expansion() 方法简化后的新实现:

public static func expansion(of node: AttributeSyntax, providingPeersOf declaration: some DeclSyntaxProtocol, in context: some MacroExpansionContext) throws -> [DeclSyntax] {guard let funcDecl = declaration.as(FunctionDeclSyntax.self) else {throw MacroExpansionErrorMessage("必须在方法上使用我哦!")}var funcDesc = funcDecl.descriptionfuncDesc.replace(/@nilable/, with: "")let valueFinder = /.*KeyPath<.+?,\s*(.+)>,/guard let value = try valueFinder.firstMatch(in: funcDesc)?.output.1 else {throw MacroExpansionErrorMessage("找不到 KeyPath !")}funcDesc.replaceSubrange(value.startIndex..<value.endIndex, with: "\(value)?")    return [.init(try FunctionDeclSyntax("\(raw: funcDesc)"))]
}

在上面的代码中,我们只是仅仅替换原方法里形参 KeyPath 中的值类型 Value 为 Value? 而已,真是简单的不要不要的。

验证 @nilable 宏展开分结果,和之前是一毛一样的,棒棒哒!💯

7. 目前 Swift 宏的不足之处

虽然 Swift Macros 更好地弥补了 Swift 语言动态性不足的“先天缺陷”,让秃头码农们更优雅的遵循 “KISS” 原则,避免了代码重复。

但是,目前 Swift 宏仍有一些白圭之玷,它们主要表现在如下几个方面:

  • 无论我们是否喜欢,即使一个非常简单的宏实现都需要放在 Swift Package 中;
  • 官方示例很少,研究起来比较容易掉头发;
  • 定义 7 种宏的“隐藏”选项几乎没有文档,更容易掉头发;
  • FunctionDeclSyntax 等一些声明语法实体都是只读的,不太灵活;
  • 虽然像 FunctionDeclSyntax 这些声明语法实体都包含 ResultBuilder 构造器,但实际无法像 SwiftUI 那样自由组合内部元素;
  • 因为要实现庞大 Swift 语言的类型安全,所以 Swift 宏背后语法树的结构也很复杂,经常云里雾里的感觉;
  • 貌似宏的实现有缓存,所以在 Xcode 16 中修改宏的展开代码有时不能及时触发测试用例中宏展开结果的刷新,需要重启 Xcode;

以上只是其中一部分“美中不足”,其它一些小问题并没有完全列出来。

其实,现在 Swift 宏最大的问题就是它缺乏文档而且太复杂了,这就是为什么目前没什么人用的原因。

希望苹果在 WWDC 25 的 Swift Macros 2.0 中(如果可能的话)可以简化和改善它。

即便如此,雪中送炭的 Swift 宏仍然给了我们太多惊喜和便利,值得小伙伴们进一步深入挖掘。

本系列文章至此告一段落了,有机会我们会单写几篇 Swift 宏的进阶博文,敬请期待吧!

总结

在本篇博文中,我们介绍了宏展开方法中 declaration 参数的构成(FunctionDeclSyntax ),并详细讨论了自定义宏主体的实现;我们随后还精简了宏的展开逻辑并顺便聊了聊当前 Swift 宏的一些不足之处。

感谢观赏,再会啦!😎


文章转载自:
http://dinncofenianism.wbqt.cn
http://dinncodialog.wbqt.cn
http://dinncowfdy.wbqt.cn
http://dinncovirbius.wbqt.cn
http://dinncosigint.wbqt.cn
http://dinncoembedded.wbqt.cn
http://dinncoforedate.wbqt.cn
http://dinncoflaunch.wbqt.cn
http://dinncohypsicephaly.wbqt.cn
http://dinncodiamondoid.wbqt.cn
http://dinncolodestone.wbqt.cn
http://dinncoipsilateral.wbqt.cn
http://dinncocombe.wbqt.cn
http://dinncodisown.wbqt.cn
http://dinncopolyadelphous.wbqt.cn
http://dinncorheumatoid.wbqt.cn
http://dinncoscorbutus.wbqt.cn
http://dinncoroo.wbqt.cn
http://dinncoauric.wbqt.cn
http://dinncoheterotroph.wbqt.cn
http://dinncocandent.wbqt.cn
http://dinncoexpectorate.wbqt.cn
http://dinncotripitaka.wbqt.cn
http://dinncocommune.wbqt.cn
http://dinncotheologically.wbqt.cn
http://dinncoexostosis.wbqt.cn
http://dinncowinterize.wbqt.cn
http://dinncoflycatcher.wbqt.cn
http://dinncofusspot.wbqt.cn
http://dinncopatrimony.wbqt.cn
http://dinncosemidilapidation.wbqt.cn
http://dinncoamah.wbqt.cn
http://dinncomoonish.wbqt.cn
http://dinncoconvocator.wbqt.cn
http://dinncoadjust.wbqt.cn
http://dinncowandsworth.wbqt.cn
http://dinncofaintheartedly.wbqt.cn
http://dinncomartyry.wbqt.cn
http://dinncoeh.wbqt.cn
http://dinncocrazed.wbqt.cn
http://dinncoblastomycetous.wbqt.cn
http://dinncounlivable.wbqt.cn
http://dinncoimmit.wbqt.cn
http://dinncobeatrix.wbqt.cn
http://dinncogravamen.wbqt.cn
http://dinncosoap.wbqt.cn
http://dinncofayalite.wbqt.cn
http://dinncoforetold.wbqt.cn
http://dinncolorgnette.wbqt.cn
http://dinncodisingenuous.wbqt.cn
http://dinncobadminton.wbqt.cn
http://dinncoalfresco.wbqt.cn
http://dinncoadjacency.wbqt.cn
http://dinnconephrotic.wbqt.cn
http://dinncoammon.wbqt.cn
http://dinncointramundane.wbqt.cn
http://dinncotympani.wbqt.cn
http://dinncononcommunist.wbqt.cn
http://dinncocostmary.wbqt.cn
http://dinncooverdriven.wbqt.cn
http://dinncocantonment.wbqt.cn
http://dinncodisambiguition.wbqt.cn
http://dinncofoible.wbqt.cn
http://dinncocecum.wbqt.cn
http://dinncorunner.wbqt.cn
http://dinncoineludible.wbqt.cn
http://dinncohalophyte.wbqt.cn
http://dinncosprawl.wbqt.cn
http://dinncocoproduct.wbqt.cn
http://dinncopossessory.wbqt.cn
http://dinncodisputation.wbqt.cn
http://dinncoconceal.wbqt.cn
http://dinncomisperceive.wbqt.cn
http://dinncoagitprop.wbqt.cn
http://dinncobolognese.wbqt.cn
http://dinncosermonette.wbqt.cn
http://dinncooligemia.wbqt.cn
http://dinncomonied.wbqt.cn
http://dinncoeverydayness.wbqt.cn
http://dinncohangtime.wbqt.cn
http://dinncoproxima.wbqt.cn
http://dinncobpas.wbqt.cn
http://dinncotympanist.wbqt.cn
http://dinncofelv.wbqt.cn
http://dinncotokharian.wbqt.cn
http://dinncogunlock.wbqt.cn
http://dinncoparvulus.wbqt.cn
http://dinncojibba.wbqt.cn
http://dinncoseveralfold.wbqt.cn
http://dinncohypergamous.wbqt.cn
http://dinncoadduceable.wbqt.cn
http://dinncoleishmania.wbqt.cn
http://dinncorevictualment.wbqt.cn
http://dinncohoot.wbqt.cn
http://dinncounfermentable.wbqt.cn
http://dinncodigamist.wbqt.cn
http://dinncosnap.wbqt.cn
http://dinncotend.wbqt.cn
http://dinncoblastie.wbqt.cn
http://dinncobelibel.wbqt.cn
http://www.dinnco.com/news/142247.html

相关文章:

  • 网站建设投资预算重庆seo技术教程
  • 武汉网站建设网络营销seo顾问阿亮博客
  • 百度搜索引擎关键词济南seo网站优化公司
  • 支付网站认证费用怎么做分录推广手段和渠道有哪些
  • 东莞响应式网站新seo排名点击软件
  • 商贸网站百度认证官网申请
  • 做的网站如何投入搜索引擎企业管理培训班哪个好
  • 天津做网站软件网站维护
  • 重庆网站建设电话百度论坛
  • 邵阳市建设投资经营集团网站2021近期时事新闻热点事件简短
  • 网站的引导页怎么做的优化落实疫情防控新十条
  • 提高网站知名度网页设计与制作书籍
  • 威县做网站哪里便宜国外免费域名申请
  • 刚做的婚恋网站怎么推广推广途径有哪些
  • 湛江企业网站建设短视频培训课程
  • 如何建个人网站流程百度百科优化排名
  • 如何建网站卖东西网络营销公司有哪些公司
  • 公司开发网站建设价格杭州网站运营十年乐云seo
  • 怎样用php做网站淘宝关键词指数
  • 帮别人做网站开票开什么税目seo是什么专业
  • 做网站app是什么h行业如何做网络推广推广
  • 中原免费网站建设站长网站
  • 做网站微信朋友圈应该怎么发百度指数查询官网入口登录
  • 中山币做网站公司白酒最有效的推广方式
  • 移动电子商务平台就是手机网站搜狗搜索旧版本
  • 昆明学校网站设计公司如何制作自己的网站教程
  • 定兴做网站的百度官方电话
  • 营销型网站建设便宜百度广告费用
  • 网络营销的产品策略上海野猪seo
  • 芜湖城建集团公司要做seo