将C#函数转换为Swift 4.2

时间:2018-10-11 10:12:23

标签: c# ios swift

我发现this thread在谈论this article。我在线程中发现了一些代码,这些代码出现正是我的项目所需要的。但是,它在C#中,我不知道如何将其转换为Swift。

C#代码:

[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
}

我需要帮助来正确翻译此函数,以便它返回小于255的47个可能的整数。

3 个答案:

答案 0 :(得分:3)

在Swift中,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
    }
}

答案 1 :(得分:1)

您的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

另外,我建议像这样为枚举设置rawValues:

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

答案 2 :(得分:1)

好吧,现在我觉得自己很白痴。 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
}

它返回与我完全一样的二进制整数。