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

[SwiftUI 开发] @dynamicCallable 与 callAsFunction:将类型实例作为函数调用

在 Swift 中,@dynamicCallable 和 callAsFunction 提供了两种将类型实例作为函数调用的方式。

1. callAsFunction

对于 callAsFunction,只需实现名为 callAsFunction 的方法,参数和返回值可自行任意定义。

例如,考虑一个ShapeCalculator结构体:

struct ShapeCalculator {func callAsFunction(length: Int, width: Double) -> Double {return Double(length) * width}func callAsFunction(radius: Double) -> Double {return 3.14 * radius * radius}func callAsFunction(side: Double) -> Double {return side * side}
}
使用示例
func runTest() -> Void {let calculator = ShapeCalculator()print("Area: \(calculator(length: 5, width: 3.0))")print("Area: \(calculator(radius: 2.0))")print("Area: \(calculator(side: 4.0))")
}
输出结果如下:
Area: 15.0
Area: 12.56
Area: 16.0

 

2:@dynamicCallable

当使用 @dynamicCallable 时,需要将此属性应用于类、结构、枚举或协议,使其类型的实例可被视为可调用函数。这要求必须实现dynamicallyCall(withArguments:)dynamicallyCall(withKeywordArguments:)其中一个或两个方法。

例如,我们创建一个StringManipulator结构体:

@dynamicCallable struct StringManipulator {func dynamicallyCall(withArguments args: [String]) -> String {var result = ""for string in args {result += string.uppercased()}return result}func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, String>) -> String {var result = ""for (key, value) in pairs {result += "\(key): \(value.uppercased())\n"}return result}
}
使用示例
func runTest() -> Void {let manipulator = StringManipulator()print("Result: \(manipulator("hello", "world"))")print("Result: \(manipulator(name: "John", age: "30"))")
}
输出结果为:
Result: HELLO WORLD
Result: NAME: JOHN
AGE: 30

 

两者的区别

1. 参数类型要求

@dynamicCallable实现的方法调用,参数类型必须一致,  参数数量可以不一样 
callAsFunction 参数类型可以不一致, 参数数量固定的

2. 方法命名要求

@dynamicCallable必须实现一个名为dynamicallyCall的方法,参数标签名称必须是withArguments或withKeywordArguments;callAsFunction必须实现一个名为callAsFunction的方法,并且参数标签可以自定义,因此callAsFunction具有更灵活的参数标签命名

3. 相同点

两者实现的方法都支持方法重载,但对于@dynamicCallable,重载方法的参数标签必须是withArguments或withKeywordArguments

相关文章:

  • 力扣9.28
  • Python按照指定“字体大小以及字体格式”,批量更新Word文档内容(10)
  • 基于Java+SQL Server2008开发的(CS界面)个人财物管理系统
  • Python编码系列—Python备忘录模式:掌握对象状态保存与恢复技术
  • HTTP请求中GET与POST方法的核心区别与用途解析
  • VMware下的ubuntu显示文字太小的自适应显示调整
  • 力扣题解2286
  • 【高分系列卫星简介——高分五号卫星(GF-5)】
  • Jenkins入门:从搭建到部署第一个Springboot项目(踩坑记录)
  • 【NodeJS】npm、yarn、pnpm当前项目设置国内镜像源
  • 【算法】分治:归并排序之LCR 170.交易逆序对的总数(hard)
  • linux脚本工具
  • 【Godot4.3】简单物理模拟之圆粒子碰撞检测
  • 【Java】虚拟机(JVM)内存模型全解析
  • RM服务器研究(一)
  • AHK 中 = 和 == 等比较运算符的用法
  • android图片蒙层
  • javascript从右向左截取指定位数字符的3种方法
  • Lucene解析 - 基本概念
  • scala基础语法(二)
  • Sequelize 中文文档 v4 - Getting started - 入门
  • 阿里云应用高可用服务公测发布
  • 大快搜索数据爬虫技术实例安装教学篇
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 码农张的Bug人生 - 见面之礼
  • 树莓派 - 使用须知
  • 数组大概知多少
  • 我从编程教室毕业
  • 小程序button引导用户授权
  • 优秀架构师必须掌握的架构思维
  • 与 ConTeXt MkIV 官方文档的接驳
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​ArcGIS Pro 如何批量删除字段
  • ‌内网穿透技术‌总结
  • # Panda3d 碰撞检测系统介绍
  • # Redis 入门到精通(七)-- redis 删除策略
  • ### RabbitMQ五种工作模式:
  • ###STL(标准模板库)
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • $.ajax()
  • $.ajax,axios,fetch三种ajax请求的区别
  • (11)iptables-仅开放指定ip访问指定端口
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (33)STM32——485实验笔记
  • (4)事件处理——(7)简单事件(Simple events)
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (八)Spring源码解析:Spring MVC
  • (纯JS)图片裁剪
  • (二)PySpark3:SparkSQL编程
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)计算机毕业设计ssm电影分享网站
  • (附源码)计算机毕业设计SSM基于健身房管理系统