我有一个名为 ProgrammingLanguage 的枚举:
enum ProgrammingLanguage {
case Swift, Haskell, Scala
}
Programmer 的类具有以下属性:let favouriteLanguages: ProgrammingLanguage = .Swift
let favouriteLanguages: ProgrammingLanguage = [.Swift, .Haskell]
OptionSetType ,但这样做时,我提出了以下 3 个错误:SetAlgebraType OptionSetType RawRepresentable case ProgrammingLanguage: String, OptionSetType {
case Swift, Haskell, Scala
}
SetAlgebraType .Int修复它(这是有道理的,因为 RawRepresentable 协议(protocol)要求您实现签名 init(rawValue: Int) 的初始化程序)。但是,我对此并不满意;我希望能够轻松获得枚举的字符串表示。OptionSetType需要一个 Int关联类型?enum ProgrammingLanguage: Int, OptionSetType {
case Swift, Scala, Haskell
}
extension ProgrammingLanguage {
init(rawValue: Int) {
self.init(rawValue: rawValue)
}
}
let programmingLanguages: ProgrammingLanguage = [.Swift, .Scala]
最佳答案
编辑:我对我以前的自己当时没有提前说这件事感到惊讶,但是......而不是试图强制其他值类型进入 OptionSet协议(protocol)(Swift 3 从名称中删除了 Type),最好考虑使用这些类型的 API 并使用 Set在适当的情况下收集。OptionSet类型很奇怪。它们既是集合又不是集合——您可以从多个标志构造一个,但结果仍然是单个值。 (您可以做一些工作来找出与此类值等效的单个标志集合,但根据类型中可能的值,它可能不是唯一的。)
另一方面,能够拥有一个东西,或者多个独特的东西,对于 API 的设计很重要。您希望用户说他们最喜欢的不止一个,还是强制要求只有一个?您想要允许多少个“收藏夹”?如果用户声称拥有多个收藏夹,是否应该按照用户特定的顺序对它们进行排名?这些都是OptionSet很难回答的问题。 -style 类型,但如果您使用 Set 则更容易类型或其他实际集合。
这个答案的其余部分 a) 是旧的,使用 Swift 2 名称,并且 b) 假设您正在尝试实现 OptionSet无论如何,即使这对您的 API 来说是一个糟糕的选择...
见docs for OptionSetType :
Supplies convenient conformance to
SetAlgebraTypefor any type whoseRawValueis aBitwiseOperationsType.
OptionSetType任何类型的一致性也采用 RawRepresentable .但是,当且仅当关联的原始值类型符合 ArrayLiteralConvertible 时,您才能获得神奇的集合代数语法支持(通过运算符和 BitwiseOperationsType 一致性)。 .String ,你运气不好——你没有获得集合代数的东西,因为 String不支持按位运算。 (这里的“有趣”之处,如果你能这么称呼的话,就是你可以扩展 String 来支持 BitwiseOperationsType ,如果你的实现满足 axioms ,你可以使用字符串作为选项集的原始值.)self.init(rawValue:)来自 init(rawValue:)一直锣直到它吹完堆栈。OptionSetType一致性,因为:ProgrammingLanguage枚举您说的是 ProgrammingLanguage 类型的值必须是 Swift 之一, Scala , 或 Haskell ,而不是其他任何东西。 “Swift 和 Scala”的值不在该集合中。 OptionSetType的底层实现基于整数位域。 “Swift 和 Haskell”值( [.Swift, .Haskell] )实际上只是 .Swift.rawValue | .Haskell.rawValue .如果您的原始值集不是位对齐的,这会导致麻烦。也就是说,如果 .Swift.rawValue == 1 == 0b01 , 和 .Haskell.rawValue == 2 == 0b10 ,这些的按位或是 0b11 == 3 , 与 .Scala.rawValue 相同. OptionSetType一致性,声明一个结构。static let声明您的类型的成员。struct ProgrammingLanguage: OptionSetType {
let rawValue: Int
// this initializer is required, but it's also automatically
// synthesized if `rawValue` is the only member, so writing it
// here is optional:
init(rawValue: Int) { self.rawValue = rawValue }
static let Swift = ProgrammingLanguage(rawValue: 0b001)
static let Haskell = ProgrammingLanguage(rawValue: 0b010)
static let Scala = ProgrammingLanguage(rawValue: 0b100)
}
static let Swift = ProgrammingLanguage(rawValue: 1 << 0)
static let Haskell = ProgrammingLanguage(rawValue: 1 << 1)
static let Scala = ProgrammingLanguage(rawValue: 1 << 2)
关于swift - OptionSetType 和枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36819163/
假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum
以下是我认为的一些下拉列表:'form-control')%>和'form-control')%>这是我的application_helper.rbdefget_advance_bookingret=[{:require_booking=>'No'},{:require_booking=>'Yes'}]enddefget_instant_bookingret=[{:instant_booking=>'No'},{:instant_booking=>'Yes'}]end但现在的问题是,在我的模型product.rb中,我无法设置具有相同名称的枚举:classProduct我收到的错误是您
我正在使用Enumerizegemhttps://github.com/brainspec/enumerize/它允许我以简单的形式使用漂亮的选择。并且此选择中的所有选项均已翻译。en:enumerize:user:sex:male:'Man'female:'Woman'所以,在我的表单中,我选择了变体“男人”和“女人”。当我用“男人”值保存记录时,我得到了“男性”值的性别属性。现在我想在显示页面上将该值显示为“Man”,但是=@user.sex输出为'male'而不是'Man' 最佳答案 我可能会使用.text方法(您可以通过使用
给定这个类:classUser我想创建一个如下所示的fixture:testuser1:id:1username:sampermission::permission_staff我尝试了多种语法变体,但没有找到有效的方法。结果user.permission为nil或0。我知道enum是最近添加的。这可以做到吗? 最佳答案 根据enumdocs你可以像这样通过类引用可枚举的:User.permissions[:permission_staff]工厂只是ruby代码——所以他们应该能够以相同的方式访问值testuser1:id:1us
我有以下数组:arr=[1,3,2,5,2,4,2,2,4,4,2,2,4,2,1,5]我想要一个包含前三个奇数元素的数组。我知道我可以做到:arr.select(&:odd?).take(3)但我想避免遍历整个数组,而是在找到第三个匹配项后返回。我想出了以下解决方案,我相信它可以满足我的要求:my_arr.each_with_object([])do|el,memo|memo但是有没有更简单/惯用的方法来做到这一点? 最佳答案 使用lazyenumerator与Enumerable#lazy:arr.lazy.select(&:o
我有一个表,'jobs'和一个枚举字段'status'。status具有以下枚举集:enumstatus:[:draft,:active,:archived]使用ransack,我如何过滤表,比如说,所有事件记录? 最佳答案 你可以像这样在模型中声明自己的掠夺者:ransacker:status,formatter:proc{|v|statuses[v]}do|parent|parent.table[:status]end然后您可以使用默认的搜索语法_eq来检查相等性,如下所示:Model.ransack(status_eq:'ac
ruby中有没有一个很好的方法来删除可枚举列表中的重复项(即拒绝等) 最佳答案 对于数组你可以使用uniq()方法a=["a","a","b","b","c"]a.uniq#=>["a","b","c"]所以如果你只是(1..10).to_a.uniq或%w{antbatcatant}.to_a.uniq因为无论如何,几乎所有您实现的方法都将作为Array类返回。 关于Ruby删除可枚举列表中的重复项,我们在StackOverflow上找到一个类似的问题: h
我想从不同线程调用一个公共(public)枚举器。当我执行以下操作时,enum=(0..1000).to_enumt1=Thread.newdopenum.nextsleep(1)endt2=Thread.newdopenum.nextsleep(1)endt1.joint2.join它引发了一个错误:Fibercalledacrossthreads.当enum在从t1调用一次后从t2调用时。为什么Ruby设计为不允许跨线程调用枚举器(或纤程),以及是否有其他方法可以提供类似的功能?我猜测枚举器/纤程上的操作的原子性在这里是相关的,但我不完全确定。如果这是问题所在,那么在使用时独占锁定
我要遍历一棵树。当我遍历它时,我保留了一堆枚举器,其中每个枚举器都用于枚举树的子级。我希望能够复制这个枚举器堆栈并将其交给另一个对象,以便它可以从堆栈状态指示的位置开始遍历树。当我尝试调用Enumerator上的#dup时,出现错误。是否可以复制枚举器?如果没有,我怎么能完成同样的事情?(我考虑过将一堆整数作为索引,但担心效率。这里有一些代码来展示我所看到的...一旦第一个枚举器启动,您就无法复制它。这就是我的情况。a=[1,2,3].each=>#a.next=>1b=a.dupTypeError:can'tcopyexecutioncontextfrom(irb):3:in`ini
例如:a=[1,2,3,4,5]a.delete_if{|x|x>3}相当于:a=[1,2,3,4,5]a.delete_if.each.each.each.each{|x|x>3}我知道a.delete_if返回一个枚举器。但是当eachblock返回true时,它如何知道应该删除对象呢?如何手动(和在Ruby中)实现delete_if? 最佳答案 可以看看Rubinius源码:enumerablemodule这里是一个拒绝方法的例子:defrejectreturnto_enum(:reject)unlessblock_giv