برنامه نویسی

ساختار در Swift: بلوک های اساسی ساختاری کد شما

وقتی برنامه نویسی را شروع می کنیم ، ما به سرعت نیاز به سازماندهی داده های خود و اقداماتی را که می توانیم بر روی آنها انجام دهیم متوجه می شویم. چگونه می توانیم “کاربر” را با نام و ایمیل آنها ، “محصول” در یک فروشگاه آنلاین با قیمت و سهام یا حتی یک “نقطه” ساده روی صفحه با مختصات X و Y نشان دهیم؟ ما به راهی برای گروه بندی اطلاعات مرتبط با واحدهای منطقی و قابل استفاده مجدد نیاز داریم.

در سوئیفت ، یکی از اساسی ترین ابزارهای این کار این کار است ساختاربشر در امتداد طبقه وت ارباب، ساختارها ستون فقرات مدل سازی داده ها را در زبان تشکیل می دهند. آنها به مراتب بیشتر از “جعبه ها” برای ذخیره داده ها هستند – آنها مؤلفه های قدرتمند و همه کاره هستند.

در این پست ، ما به دنیای ساختارها شیرجه می شویم. ما کشف خواهیم کرد که آنها چه هستند ، چگونه آنها را ایجاد کنیم ، چه چیزی می توانند در آن قرار بگیرند ، و مهمتر از همه – ما از ویژگی های تعیین کننده آنها پرده برداشتیم: بودن نوع ارزش، و چرا این یک مفهوم مهم (و اغلب سودمند) در توسعه سریع است. ممکن است تعجب کنید که در بسیاری از موارد ، ساختار انتخاب ارجح برای ساختن پایه های کد شما هستند.

ساختار چیست؟ طرح داده ها

به یک ساختار به عنوان یک طرح یا قالب فکر کنید. این نوع داده جدید و سفارشی را با مشخص کردن کدام یک تعریف می کند خواص (داده هایی که در آن نگه داشته خواهد شد) و روش (اقداماتی که می تواند انجام دهد) با آن نوع همراه است.

مقایسه:
یک طرح خانه را تصور کنید (struct House). این تعریف می کند که یک خانه تعدادی اتاق خواب خواهد داشت (bedrooms: Int) ، یک منطقه (area: Double) ، و شاید یک رنگ (color: String). همچنین می تواند اقداماتی مانند paint(newColor: String) یا calculateTax() (روش ها). هر خانه ای که از این طرح ساخته شده است (let myHouse = House(...)) نمونه ای از ساختار است.

اهداف اصلی ساختارها این است که به ما در نوشتن کد کمک کنند:

  • سازمان یافته: داده ها و رفتار مرتبط با گروه ها با هم
  • قابل خواندن: مدل های مفاهیم در دنیای واقعی یا انتزاع به وضوح
  • قابل استفاده مجدد: نوعی را تعریف می کند که می تواند در سراسر پروژه شما استفاده شود

ایجاد ساختار اول خود: دست روشن

نحو برای تعریف یک ساختار ساده است ، با استفاده از struct کلمه کلیدی:

struct Movie {
    let title: String
    var director: String
    let releaseYear: Int
    var userRating: Double?
    var watched: Bool = false
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برای ایجاد یک شیء واقعی (یک نمونه) از این “طرح” ، می توانید موارد زیر را انجام دهید:

var myFavoriteMovie = Movie(title: "Interstellar",
                            director: "Christopher Nolan",
                            releaseYear: 2014,
                            userRating: 9.5)

let anotherMovie = Movie(title: "Inception",
                         director: "Christopher Nolan",
                         releaseYear: 2010,
                         userRating: 9.2,
                         watched: true)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این که Movie(...) است ابتدای سازنده عضوبشر برای ساختار ، اگر هیچ سفارشی را تعریف نکنید init، Swift به طور خودکار مواردی را ارائه می دهد که استدلال را برای هر خاصیت ذخیره شده می پذیرد (به جز مواردی که مقادیر پیش فرض دارند ، اختیاری هستند).

پس از یک نمونه ، می توانید با استفاده از نماد DOT به خصوصیات آن دسترسی پیدا کنید:

print(myFavoriteMovie.title) // Output: Interstellar

myFavoriteMovie.watched = true
myFavoriteMovie.userRating = 10.0
print("Watched \(myFavoriteMovie.title)? \(myFavoriteMovie.watched)") // Output: true

// Trying to modify a 'let' property causes an error:
// myFavoriteMovie.releaseYear = 2015 // ERROR!

// Trying to modify any property of a 'let' instance also causes an error:
// anotherMovie.director = "Unknown" // ERROR!
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ساختار چه چیزی می تواند داشته باشد؟

ساختارها می توانند بیش از خواص ذخیره شده را شامل شوند.

1. خواص

خواص ذخیره شده:

به طور مستقیم یک مقدار را در نمونه ذخیره کنید ، مانند titleبا director، و غیره

خصوصیات محاسبه شده:

مقداری را ذخیره نکنید بلکه آن را بر اساس سایر خصوصیات محاسبه کنید. آنها همیشه با var، و شما می توانید تعریف کنید get (و به صورت اختیاری set) بلوک.

struct Circle {
    var radius: Double

    var diameter: Double {
        return radius * 2
    }

    var area: Double {
        get {
            return Double.pi * radius * radius
        }
        set(newArea) {
            guard newArea >= 0 else { return }
            radius = sqrt(newArea / Double.pi)
        }
    }
}

var myCircle = Circle(radius: 5.0)
print(myCircle.diameter) // Output: 10.0
print(myCircle.area)     // Output: ~78.54

myCircle.area = 100.0
print(myCircle.radius)   // Output: ~5.64
print(myCircle.diameter) // Output: ~11.28
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

2. روش ها

روشها توابعی هستند که در داخل ساختار تعریف می شوند ، و رفتارهای مرتبط با داده های آن را محصور می کنند.

struct Stopwatch {
    var seconds: Int = 0

    func formattedTime() -> String {
        let s = seconds % 60
        let m = (seconds / 60) % 60
        return String(format: "%02d:%02d", m, s)
    }

    mutating func tick() {
        seconds += 1
    }

    mutating func reset() {
        seconds = 0
    }
}

var myStopwatch = Stopwatch()
myStopwatch.tick()
myStopwatch.tick()
print(myStopwatch.formattedTime()) // Output: 00:02

myStopwatch.reset()
print(myStopwatch.seconds)         // Output: 0
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

چرا mutating؟

از آنجا که ساختارها انواع ارزش هستند (به زودی بیشتر در این مورد). جهش یک ویژگی به معنای جایگزینی مفهومی کل نمونه است. در mutating کلمات کلیدی سیگنال می دهد که این روش در نظر دارد وضعیت داخلی ساختار را اصلاح کند. فقط می توانید تماس بگیرید mutating روشهای موجود در موارد اعلام شده با varبشر

3. آغازگر

اولیه سازان (init) روشهای ویژه ای هستند که اطمینان می دهند همه خصوصیات ذخیره شده دارای مقدار اولیه هستند. اگر یک رسم را تعریف کنید init، شما یک عضو اتوماتیک را از دست می دهید – مگر اینکه موارد سفارشی خود را در یک پسوند تعریف کنید.

struct RGBColor {
    var red, green, blue: Double

    init(r: Int, g: Int, b: Int) {
        self.red   = max(0.0, min(1.0, Double(r) / 255.0))
        self.green = max(0.0, min(1.0, Double(g) / 255.0))
        self.blue  = max(0.0, min(1.0, Double(b) / 255.0))
    }

    init(named color: String) {
        switch color.lowercased() {
        case "red":    self.init(r: 255, g: 0, b: 0)
        case "green":  self.init(r: 0, g: 255, b: 0)
        case "blue":   self.init(r: 0, g: 0, b: 255)
        default:       self.init(r: 0, g: 0, b: 0)
        }
    }
}

let magenta = RGBColor(r: 255, g: 0, b: 255)
print("Magenta: R=\(magenta.red), G=\(magenta.green), B=\(magenta.blue)")

let green = RGBColor(named: "Green")
print("Green: R=\(green.red), G=\(green.green), B=\(green.blue)")
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ویژگی اصلی: ساختارها انواع ارزش هستند

این مهمترین مفهوم در مورد ساختارها است – و آنچه اساساً آنها را از کلاس ها جدا می کند.

منظور از نوع ارزش چیست؟

این بدان معناست که وقتی یک نمونه ساختاری را به یک متغیر جدید اختصاص می دهید یا آن را به یک عملکرد منتقل می کنید ، Swift یک نسخه کامل و مستقل ایجاد می کند از آن نمونه

struct Point {
    var x: Int
    var y: Int
}

var originalPoint = Point(x: 10, y: 20)
var copiedPoint = originalPoint

copiedPoint.x = 99

print("Original: (\(originalPoint.x), \(originalPoint.y))") // (10, 20)
print("Copy:     (\(copiedPoint.x), \(copiedPoint.y))")     // (99, 20)
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

کنتراست سریع با کلاس ها (انواع مرجع)

کلاس ها هستند انواع مرجعبشر هنگامی که یک نمونه کلاس را به متغیر دیگری اختصاص می دهید ، هر دو متغیر به همان شیء در حافظه اشاره می کنند. اگر یکی آن را تغییر دهد ، دیگری تغییر را می بیند.

قیاس ساده:

  • نوع مقدار (ساختار): مانند ساخت یک فتوکپی یک سند. دو مقاله مستقل.
  • نوع مرجع (کلاس): مانند به اشتراک گذاری یک Doc Google. همه همان سند را ویرایش می کنند.

چرا این چیز خوبی است؟

  • قابلیت پیش بینی: می دانید که انتقال یک ساختار به یک عملکرد به طور تصادفی اصل را تغییر نمی دهد.
  • ایمنی نخ: در کد چند رشته ای ، کار با نسخه های مستقل از شرایط مسابقه جلوگیری می کند.
  • عمل: ساختارها دارای پشته هستند که سریع است. Swift همچنین از کپی بر نوشتار برای جلوگیری از کپی غیر ضروری تا زمان لازم استفاده می کند.

چه زمانی باید از ساختارها در Swift استفاده کنید؟ قانون طلایی

Apple and The Swift Community توصیه می کند:

شروع کردن struct به طور پیش فرض استفاده کردن class فقط در صورت نیاز به ویژگی های خاصی که کلاس ها ارائه می دهند (مانند وراثت ، هویت یا deinitialization).

ساختارها برای:

  • مدل سازی داده های ساده: مقادیر ، اندازه گیری ها یا گروه بندی های منطقی که در آن هویت بسیار مهم نیست (به عنوان مثال ، CGPointبا CGRectبا Stringبا Arrayبا Dictionary).
  • داده های تغییر ناپذیر یا مستقل: هنگامی که هر قسمت از کد شما باید با کپی خود از داده ها کار کند.
  • نیازی به وراثت نیست: ساختارها از وراثت پشتیبانی نمی کنند. اگر به آن احتیاج دارید ، با کلاس بروید.

ساختار در مقابل کلاس ها: خلاصه تفاوت های کلیدی

نشان ساختار (نوع مقدار) کلاس (نوع مرجع)
کپی شده در تکالیف بله خیر (مرجع مشترک)
ارث هیچ بله
جهش پذیری نیازهای mutating کلمه کلیدی هدایت کردن
ذخیره شده در پشته (معمولاً) پشته
ایمنی نخ ایمن تر به احتیاط نیاز دارد
ابتدای پیش فرض اتوماتیک (عضو) به Manual Init نیاز دارد

نتیجه گیری: ساختمان با اعتماد به نفس

ساختارها بسیار بیشتر از ظروف ساده هستند. آنها بلوک های ساختمانی اساسی و همه کاره هستند که به شما امکان می دهد داده های برنامه خود را به روشی تمیز ، سازمان یافته و ایمن مدل کنید.

آنها معناشناسی ارزش یکی از بزرگترین نقاط قوت سوئیفت است که کد قابل پیش بینی و قوی را ارتقا می بخشد – به ویژه در سیستم های پیچیده یا همزمان. با درک و پذیرش ساختار (و فلسفه شروع با آنها) ، کد SWIFT IDIOMATIC ، کارآمد و قابل حفظ را می نویسید.

از استفاده از ساختارها نترسید. آنها متفقین شما در مسیر تسلط بر توسعه سوئیفت هستند. سعی کنید مفاهیم اصلی پروژه بعدی خود را با ساختار مدل سازی کنید و ببینید که کد شما چقدر تمیزتر و قابل اطمینان تر می شود.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا