我是静态类型语言的新手,想知道是否可以将 Struct 转换为其类型以调用正确的重载函数?我遇到的问题是我有一个符合 Mutation 协议(protocol)的结构列表。我想遍历列表并为每个 Struct 调用正确的 handle 函数。我可以将此 handle 函数移动到 Struct 本身,但是对于我正在尝试实现的 API,我想看看这样的事情是否可行,如下所示:
//: Playground - noun: a place where people can play
import UIKit
protocol Mutation {
func mutate(state: Int) -> Int
}
struct CountIncrement: Mutation {
func mutate(state: Int) -> Int {
return state + 1
}
}
struct CountDecrement: Mutation {
func mutate(state: Int) -> Int {
return state - 1
}
}
func handle(mutation: CountIncrement, state: Int) -> Int {
print("WILL INCREMENT")
return mutation.mutate(state: state)
}
func handle(mutation: CountDecrement, state: Int) -> Int {
print("WILL DECREMENT")
return mutation.mutate(state: state)
}
var state = 0
var queue = [CountIncrement(), CountDecrement()] as [Mutation]
for mutation in queue {
handle(mutation: mutation, state: state) // error: cannot invoke 'handle' with an argument list of type '(mutation: Mutation, state: Int)'
}
最佳答案
这与您处理问题的方式背道而驰。在 Swift 中,您通常应该避免自由函数(如 handle(mutation:state:)),而是将方法附加到类型。
你的循环需要一个特定的方法,所以你需要一个新的协议(protocol)(你当然可以把这个函数附加到Mutation,但是把它分开意味着它可以有不同的访问控制等等, so 和自由函数一样灵活)。
protocol MutationHandling {
func handleMutation(forState state: Int) -> Int
}
所以我们刚刚声明了您想要的这个功能是一个东西。现在我们可以将它附加到我们关心的事物上。这与您上面编写的自由函数完全相同。这是相同的模式。只是语法有所不同,并提供了一些额外的文档说明为什么存在此功能,并允许 IDE 提供自动完成功能并更有效地收集文档。
extension CountIncrement: MutationHandling {
func handleMutation(forState state: Int) -> Int {
print("WILL INCREMENT")
return mutate(state: state)
}
}
现在,您将此特殊协议(protocol)用于您的列表:
var queue = [CountIncrement(), CountDecrement()] as [MutationHandling]
并称它为:
for mutation in queue {
mutation.handleMutation(forState: state)
}
这不仅仅是 Swift 中的一些随机限制。这是 Swift 如何分解问题的深层部分。明确不鼓励使用自由函数(参见 API Design Guidelines )。方法和扩展是 Swift 的方式。
关于swift - 实现相同协议(protocol)的不同结构的重载函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39690654/
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.