Home > Blockchain >  Setting type of generic struct during initialization (Swift)
Setting type of generic struct during initialization (Swift)

Time:01-03

I have the following struct:

struct DataMatrix<T> : Sequence, IteratorProtocol {
    var rows: Int, columns: Int
    var headers = [String]()
    var data: [T?]
    var position = 0
    
    init(columns: Int, rows: Int, header: Bool = false) {
        self.rows = rows
        self.columns = columns
        data = Array<T?>(repeating: nil, count: rows * columns)
        if header{
            for i in 0..<columns{
                self.headers.append("Col_\(i)")
            }
        }
    }

I would now like to overload the initializer so that it will parse the elements from a string:

    init(fromString: String, separator: String){
        var finalArray = [String?]()
        let lineArray = fromString.components(separatedBy: ["\n", "\r"])
        self.rows = lineArray.count
        var maxcolumns = 0
        for currLine in lineArray{
            let arrayOfCurrLine = currLine.components(separatedBy: separator)
            if arrayOfCurrLine.count > maxcolumns{
                maxcolumns=arrayOfCurrLine.count
            }
        }
        self.columns = maxcolumns
        
        for currLine in lineArray{
            var elementsInserted = 0
            let arrayOfCurrLine = currLine.components(separatedBy: separator)
            for element in arrayOfCurrLine{
                finalArray.append(element)
                elementsInserted  = 1
            }
            if elementsInserted < maxcolumns{
                let difference = maxcolumns - elementsInserted
                for _ in 0..<difference{
                    finalArray.append(nil)
                }
            }
        }
        self.data=finalArray  ///fails
    }

The code above fails since data[T?] will not take [String?]. Typecast of self.data=finalArray as [T?] fails too.

The most elegant solution would be to set the generic type T to String? during initialization but I could not figure how to solve this. T.self=String.Type et al. does not work as T is immutable.

Any advise?

Thanks!

CodePudding user response:

All you have to do is to tell the compiler that T is a String

init(fromString: String, separator: String) where T == String {
    // ...     
}
  • Related