簡體   English   中英

如何在 Swift 中創建具有不同屬性的混合結構的數組?

[英]How to create an array with mixed structs with different properties in Swift?

我正在嘗試創建一個包含多個結構的數組,我已經創建了一個協議來這樣做,它允許我獲取和設置相似的屬性,但當屬性不同時不能。 我現在的代碼如下:

結構:

struct A: Pr {
poll: String
res: Int
}

struct B: Pr {
poll:String
ont: String
}

協議:

protocol Pr {
   var poll:String { get set }
}

沒有初始化的 var 類型:

var field:[Pr]

稍微清理一下代碼后:

protocol Pr {
   var poll:String { get set }
}

struct A: Pr {
  var poll: String
  var res: Int
}

struct B: Pr {
  var poll:String
  var ont: String
}

var field: [Pr]

如果我明白你想要的是這樣的:

// Just an example to fill array with something for a demo:
let a = A(poll: "pollA", res: 1)
let b = B(poll: "pollB", ont: "ont")

field = [Pr]()
field.append(a)
field.append(b)

// The actual solution
for pr in field {

    print(pr.poll)

    switch pr {
    case let pr as A:
        print(pr.res)
    case let pr as B:
        print(pr.ont)
    default:
        print("no more properties")
    }
}

也就是說:您可以將數組中的每個項目轉換為給定類型,以獲取特定於該類型的屬性。 這解決了GET問題。 Set 更復雜,因為您有一個數組和結構,在修改時會被復制。 所以從技術上講,你可以改變它們,但它不會是同一個實例。 解決此問題的最簡單方法是使用 function 返回一個修改后的[Pr]對象數組,您可以將其分配回field

func modify() -> [Pr] {

    var result = [Pr]()

    for pr in field {

        switch pr {
        case let pr as A:
            let a = A(poll: pr.poll + "changed", res: pr.res + 1)
            result.append(a)
        case let pr as B:
            let b = B(poll: pr.poll + "changed", ont: pr.ont + "changed")
            result.append(b)
        default:
            print("skip")
        }
    }

    return result
}

field = modify()

但是,如果您要處理大量數據、大量副本等,這可能不是一個好的解決方案……因此,需要一個更具體的用例來使答案更有用。

你有兩個問題:

  1. 符合Pr協議的結構數組不是AB對象的數組:

  2. Array 和 Struct 類型都是值類型,因此您不能在不復制的情況下將數組中的條目轉換為特定的具體類型。

此代碼解決了問題 1,但沒有解決問題 2:

(field[0] as? A)?.res = 5

除了將 A 和 B 轉換為class (引用類型)對象之外,我不確定是否有解決您的問題的方法。 此代碼有效:

protocol Pr {
   var poll:String { get set }
}

class A: Pr, CustomStringConvertible {
    var poll: String
    var res: Int
    
    init(poll: String, res: Int) {
        self.poll = poll
        self.res = res
    }
    
    var description: String {
        return ("A(poll: \(poll), res:\(res))")
    }
}

class B: Pr, CustomStringConvertible {
    var poll:String
    var ont: String

    init(poll: String, ont: String) {
        self.poll = poll
        self.ont = ont
    }
    var description: String {
        return ("B(poll: \(poll), ont:\(ont))")
    }
}

var field:[Pr] = [A(poll:"h", res:3), B(poll:"c", ont:"o"),]
field[0].poll = "p"
field[1].poll = "q"

(field[0] as? A)?.res = 5

(field[1] as? B)?.ont = "z"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM