代码之家  ›  专栏  ›  技术社区  ›  E. Huckabee

将C#函数转换为Swift 4.2

  •  0
  • E. Huckabee  · 技术社区  · 6 年前

    我发现 this thread 谈论 this article . 我在线程中发现了一些代码 成为我的项目所需要的。但是,它是用C#写的,我不知道如何把它翻译成Swift。

    [Flags]
    public enum Directions
    {
        NorthWest  = 1 << 0,
        North = 1 << 1,
        NorthEast   = 1 << 2,
        West   = 1 << 3,
        East  = 1 << 4,
        SouthWest = 1 << 5,
        South   = 1 << 6,
        SouthEast   = 1 << 7,
    }
    
    private static Directions CalculateTileFlags(bool east, bool west, bool north, bool south, bool northWest, bool northEast, bool southWest, bool southEast)
    {
        var directions = (east ? Directions.East : 0) | (west ? Directions.West : 0)  | (north ? Directions.North : 0) | (south ? Directions.South : 0);
        directions |= ((north && west) && northWest) ? Directions.NorthWest : 0;
        directions |= ((north && east) && northEast) ? Directions.NorthEast : 0;
        directions |= ((south && west) && southWest) ? Directions.SouthWest : 0;
        directions |= ((south && east) && southEast) ? Directions.SouthEast : 0;
        return directions;
    }
    

    var Flags = [Int]()
    enum Directions : Int {
        case NorthWest
        case North
        case NorthEast
        case West
        case East
        case SouthWest
        case South
        case SouthEast
    
        func getTuple() -> Int {
            switch self {
            case .NorthWest:
                return 1 << 0
            case .North:
                return 1 << 1
            case .NorthEast:
                return 1 << 2
            case .West:
                return 1 << 3
            case .East:
                return 1 << 4
            case .SouthWest:
                return 1 << 5
            case .South:
                return 1 << 6
            case .SouthEast:
                return 1 << 7
            }
        }
    }
    

    我明白了。很简单。函数是我不太明白的部分。我想我很接近,但我不知道。

    func CalculateTileFlags(east: Bool, west: Bool, north: Bool, south: Bool,
                                northWest: Bool, northEast: Bool, southWest: Bool, southEast: Bool) -> Int {
    
        var eastD = Directions.East.getTuple()
        var westD = Directions.West.getTuple()
        var northD = Directions.North.getTuple()
        var southD = Directions.South.getTuple()
        var northWestD = Directions.NorthWest.getTuple()
        var northEastD = Directions.NorthEast.getTuple()
        var southWestD = Directions.SouthWest.getTuple()
        var southEastD = Directions.SouthEast.getTuple()
    
        var directions = east ? true : false || west ? true : false || north ? true : false || south ? true : false
    
        directions != ((north && west) && northWest) ? northWestD : 0
        directions != ((north && east) && northEast) ? northEastD : 0
        directions != ((south && west) && southWest) ? southWestD : 0
        directions != ((south && east) && southEast) ? southEastD : 0
    
        return directions
    }
    

    3 回复  |  直到 6 年前
        1
  •  3
  •   OOPer    6 年前

    在斯威夫特, OptionSet 是最接近其他语言的位移位值枚举的数据结构:

    您的C代码可以翻译如下:

    struct Directions: OptionSet {
        var rawValue: Int
        init(rawValue: Int) {self.rawValue = rawValue}
    
        static let northWest = Directions(rawValue: 1 << 0)
        static let north     = Directions(rawValue: 1 << 1)
        static let northEast = Directions(rawValue: 1 << 2)
        static let west      = Directions(rawValue: 1 << 3)
        static let east      = Directions(rawValue: 1 << 4)
        static let southWest = Directions(rawValue: 1 << 5)
        static let south     = Directions(rawValue: 1 << 6)
        static let southEast = Directions(rawValue: 1 << 7)
    }
    
    extension Directions {
        static func calculateTileFlags(
            east: Bool = false,
            west: Bool = false,
            north: Bool = false,
            south: Bool = false,
            northWest: Bool = false,
            northEast: Bool = false,
            southWest: Bool = false,
            southEast: Bool = false) -> Directions
        {
            var directions: Directions = [
                east ? Directions.east : [],
                west ? Directions.west : [],
                north ? Directions.north : [],
                south ? Directions.south : [],
            ]
    
            directions.formUnion((north && west) && northWest ? Directions.northWest : [])
            directions.formUnion((north && east) && northEast ? Directions.northEast : [])
            directions.formUnion((south && west) && southWest ? Directions.southWest : [])
            directions.formUnion((south && east) && southEast ? Directions.southEast : [])
    
            return directions
        }
    }
    
        2
  •  1
  •   vacawama    6 年前

    您的初始值 directions 不正确。您应该使用方向布尔来选择值或 0

    另外,您正在使用 != 这是一个布尔比较,而不是 |= 是二进制或运算。

    试试这个:

    var directions = (east ? eastD : 0) | (west ? westD : 0)  | (north ? northD : 0) | (south ? southD : 0)
    
    directions |= ((north && west) && northWest) ? northWestD : 0
    directions |= ((north && east) && northEast) ? northEastD : 0
    directions |= ((south && west) && southWest) ? southWestD : 0
    directions |= ((south && east) && southEast) ? southEastD : 0
    
    return directions
    

    另外,我建议只设置枚举的rawValue,如下所示:

    enum Directions : Int {
        case NorthWest = 1    // 1 << 0
        case North     = 2    // 1 << 1
        case NorthEast = 4    // 1 << 2
        case West      = 8    // 1 << 3
        case East      = 16   // 1 << 4
        case SouthWest = 32   // 1 << 5
        case South     = 64   // 1 << 6
        case SouthEast = 128  // 1 << 7
    }
    

    而不是 Directions.East.getTuple() 你会用 Directions.East.rawValue

        3
  •  1
  •   E. Huckabee    6 年前

    好吧,现在我觉得自己像个白痴。C#和Swift都是基于C的语言,因此它们具有相似的功能和相似的操作。在这种情况下,这几乎是一个直接的翻译。

    最终翻译代码:

    enum Dir : Int {
        case NorthWest = 1
        case North     = 2
        case NorthEast = 4
        case West      = 8
        case East      = 16
        case SouthWest = 32
        case South     = 64
        case SouthEast = 128
    }
    

    以及功能:

    func CalculateTileFlags(east: Bool, west: Bool, north: Bool, south: Bool,
                            northWest: Bool, northEast: Bool, southWest: Bool, southEast: Bool) -> Int {
    
        var directions = (east ? Dir.East.rawValue : 0) | (west ? Dir.West.rawValue : 0)  | (north ? Dir.North.rawValue : 0) | (south ? Dir.South.rawValue : 0)
    
        directions |= ((north && west) && northWest) ? Dir.NorthWest.rawValue : 0
        directions |= ((north && east) && northEast) ? Dir.NorthEast.rawValue : 0
        directions |= ((south && west) && southWest) ? Dir.SouthWest.rawValue : 0
        directions |= ((south && east) && southEast) ? Dir.SouthEast.rawValue : 0
    
        return directions
    }
    

    它返回一个与我需要的完全相同的二进制整数。