语法(六) – 嵌套函数、类以及结构体

温馨提示:本文最后更新于2024-07-28 10:13:12,某些文章具有时效性,若有错误或已失效,请在下方留言

Swift 允许将一种数据类型嵌套在另一种数据类型中,常用来按照逻辑行为对事物进行归类,但有时也会附加访问语义,以防止嵌套数据类型被错误使用。

使用嵌套类型进行逻辑分组。

enum London {
    static let coordinates = (lat: 51.507222, long: -0.1275)
    
    enum Subwaylines {
        case bakerloo, central, circle, district, hammersmithCity, jubilee, metropolitan, northern, piccadilly, victoria, waterlooCity
    }
    
    enum Places {
        case buckinghamPalace, cityHall, oldBailey, piccadilly, stPaulsCathedral
    }
}

可以将它用于故事板 ID、表格视图单元 ID、图像名称等。

enum R {
    enum Storyboards: String {
        case main, detail, upgrade, share, help
    }

    enum Images: String {
        case welcome, home, about, button
    }
}

嵌套类型还可与其他数据类型一起使用。

struct Cat {
    enum Breed {
        case britishShortHair, burmese, persian, ragdoll, russianBlue, scottishFold, siamese
    }

    var name: String
    var breed: Breed
}

语义嵌套

Swift 允许为嵌套类型指定访问控制修饰符,以控制它们的使用方式。

struct Deck {
    struct Card {
        private enum Suit {
            case hearts, diamonds, clubs, spades
        }

        var rank: Int
        private var suit: Suit
    }

    var cards = [Card]()
}

如果我们希望 Suit 枚举是私有的,这样只有 Card 实例才能使用它,我们就需要使用 private enum Suit

嵌套函数

Swift 将嵌套函数实现为命名闭包,这意味着它们会自动从外层函数中获取值。

import Foundation

struct Point {
    let x: Double
    let y: Double
}

enum DistanceTechnique {
    case euclidean
    case euclideanSquared
    case manhattan
}

func calculateDistance(start: Point, end: Point, technique: DistanceTechnique) -> Double {
    func calculateEuclideanDistanceSquared() -> Double {
        // 自动从外层函数中获取值
        let deltaX = start.x - end.x
        let deltaY = start.y - end.y
        
        return deltaX * deltaX + deltaY * deltaY
    }
    
    func calculateEuclideanDistance() -> Double {
        return sqrt(calculateEuclideanDistanceSquared())
    }

    func calculateManhattanDistance() -> Double {
        // 自动从外层函数中获取值start以及end
        return abs(start.x - end.x) + abs(start.y - end.y)
    }

    switch technique {
    case .euclidean:
        return calculateEuclideanDistance()
    case .euclideanSquared:
        return calculateEuclideanDistanceSquared()
    case .manhattan:
        return calculateManhattanDistance()
    }
}

返回嵌套函数

func createDistanceAlgorithm(technique: DistanceTechnique) -> (Point, Point) -> Double {
    func calculateEuclideanDistanceSquared(start: Point, end: Point) -> Double {
        let deltaX = start.x - end.x
        let deltaY = start.y - end.y

        return deltaX * deltaX + deltaY * deltaY
    }

    func calculateEuclideanDistance(start: Point, end: Point) -> Double {
        return sqrt(calculateEuclideanDistanceSquared(start: start, end: end))
    }

    func calculateManhattanDistance(start: Point, end: Point) -> Double {
        return abs(start.x - end.x) + abs(start.y - end.y)
    }

    switch technique {
    case .euclidean:
        return calculateEuclideanDistance
    case .euclideanSquared:
        return calculateEuclideanDistanceSquared
    case .manhattan:
        return calculateManhattanDistance
    }
}

这三个函数中的每一个现在都需要接受参数,因为它们稍后会像这样被调用:

let distanceAlgorithm = createDistanceAlgorithm(technique: .euclidean)
let distance = distanceAlgorithm(Point(x: 10, y: 10), Point(x: 100, y: 100))

– 《Pro Swift》
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容