如何在swift中编写通用工厂方法?

2023-12-22

我不知道如何(如果可能的话)编写调用从常见已知基类 继承的泛型类型的构造函数的方法,以创建 T 的一些实例,而无需求助于显式工厂函数,即使用所有花哨的功能由类型推断提供。

在操场上运行的示例:

// Let there be classes MyPod and Boomstick with common Base (not important)
class Base : Printable {
    let value : String; init(_ value : String) { self.value = "Base." + value }
    var description: String { return value }
}
class MyPod : Base {
    init(_ value: String) { super.init("MyPod." + value) }
}
class Boomstick : Base {
    init(_ value: String) { super.init("Boomstick." + value) }
}
// PROBLEM: do not know how to force call of Boomstick(n) instead of Base(n) in here
func createSome<T : Base>() -> T[] {
    var result = Array<T>()
    for n in 1...5 {
        result += T(toString(n))
    }
    return result
}
// This seems to be fine. 
// I was expecting call of createSome<Boomstick>() { ... result += Boomstick(n) ...
let objs : Boomstick[] = createSome() 
// Prints: Base.1, Base.2, ... not much wished Boomstick.1, Boomstick.2, ...
println(objs)

一种明显的解决方案是将创建委托给调用者,但这似乎很笨拙:

func createSome<T>(factory : (Int)->T) { ... }

谢谢。

PS:将 createSome()->Base[] 赋值给 objs:Boomstick[] 是否违反类型安全?


目前我还没有关于这个问题的答案why,但使用初始化器定义协议似乎只起作用:

protocol A {
    init(_ value: String)
}

您可以在所有类中实现此协议,如下所示

class Base : Printable, A {
    let value : String;
    init(_ value : String) { self.value = "Base." + value }
    var description: String { return value }
}

class MyPod : Base, A {
    init(_ value: String) { super.init("MyPod." + value) }
}

class Boomstick : Base, A {
    init(_ value: String) { super.init("Boomstick." + value) }
}

and use A而不是Base在你的createSome() func

func createSome<T : A>() -> [T] {
    var result = Array<T>()
    for n in 1...5 {
        result += T(toString(n))
    }
    return result
}

在操场上测试:

let objs : [Boomstick] = createSome()
objs[0]

它打印:

{value "Base.Boomstick.1"}

还尝试使用MyPod and Base它打印了预期的结果。 测试一下,让我知道它是否也适合您。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在swift中编写通用工厂方法? 的相关文章

随机推荐

  • 如何解决重叠轴刻度标签

    我正在研究来自 SDSS 斯隆数字巡天 的数据来绘制和分析恒星的光谱 为此 我从他们的网站下载了一个 csv 文件 从中提取每一行及其数据 然后绘制该数据 数据的格式为波长 通量 最佳拟合 SkyFlux 但我只对波长和最佳拟合真正感兴趣
  • Android模拟器太慢了,无法使用

    我对Android模拟器的体验是它太慢了以至于无法使用 我看到与该问题相关的线索可以追溯到一年多前 对问题缺乏一致的回答是不可接受的 这不是社区的错 问题 有谁经历过速度极其缓慢 启动时间超过 15 分钟 实际解决了这个问题使得启动时间不到
  • 使用 JQuery 将 拖放到段落中

    我需要拖放 span to p 我的代码可以运行 但有 3 个问题 当我编辑时 p p 通过输入内容 假设三个单词 并拖动后 span to span p p 新输入的单词充当一个单词 因此不能在这些新输入的内容之间放置可拖动组件 关闭后
  • “NODE_OPTIONS”未被识别为内部或外部命令 - 仍然是一个问题

    我正在遵循以下指南here https nextjs org docs advanced features debugging在 nextjs 应用程序上 在 Windows 上使用 VSCode 它说使用脚本 dev NODE OPTIO
  • 如何在 Windows 应用商店应用程序 C# 中读取 mp3 文件的每分钟节拍数标签?

    我正在尝试读取嵌入在 mp3 文件中的 bpm 如下所示 我尝试过使用 Windows Storage FileProperties MusicProperties 但它只包含标题 歌手等 它无法读取我之前显示的 bpm 我正在调查http
  • 仅重用 Crystal Reports 刷新时的某些参数?

    我有一个水晶报表 它有两个参数 其中之一由运行报表的 C 应用程序自动设置 但另一个由用户设置 我想这样做 以便当用户刷新报表时 仅提示用户输入的参数 我知道 ReuseParameterValuesOnRefresh 属性 但这使得所有参
  • wso2 Esb 中代理服务和 API 服务的区别

    wso2esb 中的代理服务和 API 服务有什么区别 为了公开我的服务 我可以提供代理 URL 和 API URL 那么在哪种情况下两者会有所不同 在什么情况下可以使用代理 在什么情况下可以使用API 请帮助我理解 API 具有资源 因此
  • Apache-HttpComponents:套接字关闭错误

    我正在编写一个 Java 程序 它使用 Apache HttpComponents 加载页面并将其 HTML 打印到控制台 但是 该程序在抛出此错误之前仅打印部分 HTML Exception in thread main java net
  • 使用 fs.writeFile() 在 Node.js 中创建 .wav 文件

    我正在尝试创建一个 wav从 Node JS 中的数据块中读取文件 使用fs writeFile 首先 这可能吗 我目前正在尝试这个 fs writeFile filename wav blob recording function err
  • 文档数据库中架构更改的模式

    在我开始之前我想为此道歉 我的问题的通用类型 我确信整本书 可以就该特定主题进行写作 假设您有一个包含多个文档模式的大型文档数据库 以及每个模式的数百万个文档 在应用程序的生命周期中 需要更改架构 经常查看已存储的文档 和内容 这样的改变可
  • 将数据帧分成两部分并使用波形符 ~ 作为变量

    我想在 Python 3 中用 Pandas 做 2 个类似的操作 一个带波浪号 另一个不带波浪号 1 df df df teste isin Place 2 df df df teste isin Place 我尝试将波形符声明为变量 这
  • 如果列表中存在某个项目,如何删除该项目?

    我正进入 状态new tag从表单文本字段self response get new tag and selected tags来自复选框字段 self response get all selected tags 我这样组合它们 tag
  • 将输入类型文本转换为密码[重复]

    这个问题在这里已经有答案了 我想在点击时将输入类型更改为密码 我试过这个
  • PHP:如果未设置则分配 null?

    PHP 中是否有任何类型的 if not empty otherwise assign null 函数 我正在寻找一种更清洁的替代方案 variable empty item item NULL 如果我可以指定默认值也会很方便 例如 有时我
  • 使用 PHP 过滤 XML 文件

    我想加载 XML 文件 然后删除所有
  • 任务“:bootRun”执行失败。 > 进程“命令”C:\Program Files\Java\jdk-9.0.4\bin\java.exe'' 已完成,退出值非零 1

    我一直在到处寻找如何解决这个问题 我发现了类似的问题 并尝试了一切 但没有任何帮助 重新安装 Java 和 gradle 没有帮助 这里是错误的堆栈跟踪 Task bootRun Spring Boot
  • mongo 的简短用户友好 ID

    我正在创建一个实时股票交易系统 并希望为用户提供一种人类可读 用户友好的方式来参考他们的订单 例如 ID 的长度应为 8 个字符 并且仅包含大写字符 例如Z9CFL8BA 由于显而易见的原因 id 在系统中需要是唯一的 我使用 MongoD
  • 通过 emacs -nw 打开多个垂直分割的文件

    Using emacs nw file1 file2我可以一次打开多个文件 然而 emacs 将以水平分割方式打开它们 有没有办法将默认分割行为设置为垂直 我看过 切换窗口分割 http www emacswiki org emacs To
  • Micronaut:如何获取 Prometheus 格式的指标?

    我应该如何配置 Micronaut 才能获得 metrics普罗米修斯格式 Used 微型机器人1 0 0 M3 Now micronaut metrics enabled true export prometheus enabled tr
  • 如何在swift中编写通用工厂方法?

    我不知道如何 如果可能的话 编写调用从常见已知基类 继承的泛型类型的构造函数的方法 以创建 T 的一些实例 而无需求助于显式工厂函数 即使用所有花哨的功能由类型推断提供 在操场上运行的示例 Let there be classes MyPo