我如何接受两种类型之一作为函数的参数?

问题描述 投票:0回答:2

我想编写一个函数,仅接受

Int
Double
并根据它们返回不同的值。实际用例的特点是 SwiftUI
struct: View
具有更复杂的
init()
。如果可能的话,我想避免使用不同的输入类型重复它。这怎么办?

理想情况下,我想要一个如下所示的解决方案:

struct MyStruct<T>: View where T is (Int | Double) {  // Specifying type here is the problematic part
var value: T
var description: String

init(_ value: T) {
   self.value = value
   switch value {
      case is Int:
         description = "Integer"
      case is Double:
         description = "Double"
   }
}

var body: some View {
   Text(description)
}
swift generics swiftui
2个回答
0
投票

至少有两个选择:

  1. Int
    Double
    在扩展中采用的自定义虚拟协议

    protocol IntOrDouble {}
    extension Int : IntOrDouble {}
    extension Double : IntOrDouble {}
    
    struct MyStruct<T>: View where T : IntOrDouble {
        var value: T
        let description: String
    
        init(_ value: T) {
           self.value = value
            description = value is Int ? "Integer" : "Double"
        }
    
        var body: some View {
            Text(description)
        }
    }
    
  2. 具有关联值的枚举

    enum IntOrDouble {
        case integer(Int)
        case double(Double)
    }
    
    struct MyStruct: View, CustomStringConvertible {
        var value: IntOrDouble
    
        var body: some View {
            Text(description)
        }
    
        var description : String {
            switch value {
                case .integer(let intValue):
                    return "Integer \(intValue)"
                case .double(let doubleValue):
                    return "Double \(doubleValue)"
            }
        }
    }
    

0
投票

一般来说,泛型用于支持不同的类型。但当你只想只支持

Int
Double
时,我认为你可以这样做:

import SwiftUI

protocol MyType {
    var typeDescription: String { get }
}

extension Int: MyType {
    var typeDescription: String {
        return "Integer"
    }
}

extension Double: MyType {
    var typeDescription: String {
        return "Double"
    }
}

struct MyStruct<T: MyType>: View {
    var value: T
    
    var body: some View {
        Text(value.typeDescription)
    }
}

#Preview {
    MyStruct(value: 2) // Integer
    //MyStruct(value: 2.3) // Double
}

© www.soinside.com 2019 - 2024. All rights reserved.