在Swift中获取多维数组的元素类型

I want custom Multi-dimensional Array in Swift. I declared MArray such like;

class MArray{
    private var flatten: [Any]
    private var shape: [Int]
    init(_ marray: [Any]){
         var shape: [Int] = []
         var marray: [Any] = marray
         (self.flatten, self.shape) = _call_flatten_row_major(&marray, &shape)
    }
}
fileprivate func _call_flatten_row_major(_ queue: inout [Any], _ shape: inout [Int]) -> (flatten: [Any], shape: [Int]){
    shape = [queue.count]
    return (_get_flatten_row_major(&queue, &shape), shape)
}
//breadth-first search
fileprivate func _get_flatten_row_major(_ queue: inout [Any], _ shape: inout [Int]) -> [Any]{
    precondition(shape.count == 1, "shape must have only one element")
    var cnt = 0 // count up the number that value is extracted from queue for while statement, reset 0 when iteration number reaches size
    var size = queue.count
    var axis = 0//the axis in searching

    while queue.count > 0 {
        //get first element
        let elements = queue[0]

        if let elements = elements as? [Any]{
            queue += elements

            if cnt == 0{ //append next dim
                shape.append(elements.count)
                axis += 1
            }
            else{// check if same dim is or not
                if shape[axis] != elements.count{
                    shape = shape.dropLast()
                }
            }
            cnt += 1
        }
        else{ // value was detected. this means queue in this case becomes flatten array
            break
        }
        //remove first element from array
        let _ = queue.removeFirst()

        if cnt == size{//reset count and forward next axis
            cnt = 0
            size *= shape[axis]
        }
    }

    return queue
}

However, as you can see, the argument of this MArray's initializer is [Any]. That is why MArray can't get flatten's type. Namely, MArray can't get Multi-dimensional Array's type.

然后,我使用了类似的泛型;

class MArray<T>{
    private var flatten: [T]
    private var shape: [Int]
    init(_ marray: [Any]){
         (self.flatten, self.shape): [T], [Int] = _call_flatten_row_major(&marray, &shape)
    }
}

和,

fileprivate func _call_flatten_row_major<T>(_ queue: inout [Any], _ shape: inout [Int]) -> (flatten: [T], shape: [Int]){
    shape = [queue.count]
    return (_get_flatten_row_major(&queue, &shape) as! [T], shape)
}

When I declared MArray<Int>([[1,2,3]]), it is OK. But when I declared MArray<Float>([[1,2,3]]),

无法将类型'Swift.Int'(0x7fff8b682600)的值强制转换为'Swift.Float'(0x7fff8b6825e0)。

I want Compiler to understand MArray<Float>([[1,2,3]])'s flatten type is Float.... (I should use ExpressibleByArrayLiteral??)

You may think that all I have to do is declaring MArray<Float>([[Float(1),Float(2),Float(3)]]). But Float(number) is annoying!!

  • How can I get multi-dimensional Array's element type?
  • Should I use ExpressibleByArrayLiteral to achieve this? and if so, please tell me tips to use ExpressibleByArrayLiteral for Multi-dimensional Array...
评论