考虑:
enum Line {
case Horizontal(CGFloat)
case Vertical(CGFloat)
}
let leftEdge = Line.Horizontal(0.0)
let leftMaskRightEdge = Line.Horizontal(0.05)
Run Code Online (Sandbox Code Playgroud)
如何在lefEdge不使用switch语句的情况下直接访问相关值?
let noIdeaHowTo = leftEdge.associatedValue + 0.5
Run Code Online (Sandbox Code Playgroud)
这甚至没有编译!
我看了一下这些 SO 问题,但没有一个答案似乎解决这个问题.
noIdeaHowTo上面的非编译行应该是单行,但由于associated value可以是任何类型,我甚至无法看到用户代码如何在le enum本身中编写"泛型"get或associatedValue方法.
我最终得到了这个,但它很严重,每次我添加/修改案例时都需要我重新访问代码...
enum Line {
case Horizontal(CGFloat)
case Vertical(CGFloat)
var associatedValue: CGFloat {
get {
switch self {
case .Horizontal(let value): return value
case .Vertical(let value): return value
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
有人指点吗?
ver*_*rec 69
正如其他人所指出的,现在Swift 2中有可能实现这一点:
import CoreGraphics
enum Line {
case Horizontal(CGFloat)
case Vertical(CGFloat)
}
let min = Line.Horizontal(0.0)
let mid = Line.Horizontal(0.5)
let max = Line.Horizontal(1.0)
func doToLine(line: Line) -> CGFloat? {
if case .Horizontal(let value) = line {
return value
}
return .None
}
doToLine(min) // prints 0
doToLine(mid) // prints 0.5
doToLine(max) // prints 1
Run Code Online (Sandbox Code Playgroud)
小智 9
您可以使用保护语句来访问关联的值,如下所示。
enum Line {
case Horizontal(Float)
case Vertical(Float)
}
let leftEdge = Line.Horizontal(0.0)
let leftMaskRightEdge = Line.Horizontal(0.05)
guard case .Horizontal(let leftEdgeValue) = leftEdge else { fatalError() }
print(leftEdgeValue)
Run Code Online (Sandbox Code Playgroud)
您可以使用 if case let 语法在不使用开关的情况下获取关联值:
enum Messages {
case ping
case say(message: String)
}
let val = Messages.say(message: "Hello")
if case let .say(msg) = val {
print(msg)
}
Run Code Online (Sandbox Code Playgroud)
如果枚举值为 .say,则 if case let 内的块将运行,并且范围内的关联值将作为您在 if 语句中使用的变量名。
我想你可能会尝试使用enum它不适合的东西.访问相关值的方法确实是通过switch你已经完成的,这个想法是switch总是处理每个可能的成员情况enum.
不同成员enum可以有不同的相关值(例如,你可以有Diagonal(CGFloat, CGFloat)和Text(String)你enum Line),所以你必须确认你正在处理,然后才能访问相关值的情况.例如,考虑:
enum Line {
case Horizontal(CGFloat)
case Vertical(CGFloat)
case Diagonal(CGFloat, CGFloat)
case Text(String)
}
var myLine = someFunctionReturningEnumLine()
let value = myLine.associatedValue // <- type?
Run Code Online (Sandbox Code Playgroud)
你怎么能冒昧地得到相应的数值myLine时,有可能与你打交道CGFloat,String或者2个 CGFloat S' 这就是为什么你需要switch首先发现case你拥有的.
在您的特定情况下,它听起来就像你可能是一个更好的关闭class或struct进行Line,那么这可能会存储CGFloat,也有一个enum财产Vertical和Horizontal.或者您可以建模Vertical并Horizontal作为单独的类,Line作为协议(例如).
为什么这是不可能的已经回答了,所以这只是一个建议。你为什么不这样实现它。我的意思是枚举和结构都是值类型。
enum Orientation {
case Horizontal
case Vertical
}
struct Line {
let orientation : Orientation
let value : CGFloat
init(_ orientation: Orientation, _ value: CGFloat) {
self.orientation = orientation
self.value = value
}
}
let x = Line(.Horizontal, 20.0)
// if you want that syntax 'Line.Horizontal(0.0)' you could fake it like this
struct Line {
let orientation : Orientation
let value : CGFloat
private init(_ orientation: Orientation, _ value: CGFloat) {
self.orientation = orientation
self.value = value
}
static func Horizontal(value: CGFloat) -> Line { return Line(.Horizontal, value) }
static func Vertical(value: CGFloat) -> Line { return Line(.Vertical, value) }
}
let y = Line.Horizontal(20.0)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20729 次 |
| 最近记录: |