structure یا به اختصار struct نوعی ساختار داده در سوئیفت هست که به ما اجازه میدهد چند داده مرتبط را در کنار هم نگهداری کنیم.
برای مثال فرض کنید میخواهیم اطلاعات یک دانشجو مثل شماره دانشجویی، نام و عکس او را ذخیره کنیم. اگر بخواهیم هر کدام را جداگانه در متغیر های مختلف قرار دهیم کد ما شلوغ و مدیریت آن سخت میشود.
در چنین مواقعی میتوانیم از Struct استفاده کنیم تا تمام اطلاعات مربوط به یک چیز را در یک ساختار واحد قرار دهیم.
برای تعریف یک struct از کلمه کلیدی struct استفاده میکنیم و سپس متغیر هایی که نیاز داریم را درون آن تعریف میکنیم.
struct Student {
var stdNum: Int
var name: String
var image: String
}
Student فقط یک مثال است. شما میتوانید هر نام دیگری که مناسب ساختار داده شما باشد انتخاب کنید.بعد از تعریف struct میتوانیم از آن نمونه (instance) بسازیم.
برای این کار کافی است یک متغیر تعریف کنیم و سپس نام struct را بنویسیم و مقدار متغیر هایی که در آن تعریف کرده ایم را مشخص کنیم.
var std = Student(
stdNum: 10044,
name: "Milad",
image: "image1"
)
برای دسترسی به متغیر های داخل یک struct کافی است نام نمونه را بنویسیم و بعد از آن با استفاده از نقطه (.) به متغیر مورد نظر دسترسی پیدا کنیم.
var elena = Student(
stdNum: 10092,
name: "Elena",
image: "image2"
)
print(elena.stdNum)
خروجی:
10092
درون struct ها علاوه بر متغیر، میتوانیم تابع (method) هم تعریف کنیم.
این تابع میتواند به متغیر های داخل struct دسترسی داشته باشد.
struct Songs {
var year: Int
var songName: String
var img: String
func play() {
print("I'm playing \(songName) and it was released in \(year)")
}
}
حالا یک نمونه از این struct میسازیم و تابع آن را اجرا میکنیم.
var taylorSwift = Songs(
year: 2020,
songName: "Willow",
img: "willow-img"
)
taylorSwift.play()
خروجی:
I'm playing Willow and it was released in 2020
گاهی اوقات ممکن است یک متغیر همیشه مقدار نداشته باشد.
برای مثال فرض کنید در یک فرم ثبت نام یک فیلد برای پیشنهادات قرار داده ایم. ممکن است کاربر آن را پر کند یا ممکن است خالی بگذارد.
در چنین شرایطی میتوانیم متغیر را به صورت optional تعریف کنیم و از علامت ? استفاده کنیم.
struct Forms {
var name: String
var job: String
var suggest: String?
}
let member = Forms(
name: "Fatma",
job: "Swift programmer"
)
Initializer ها با استفاده از کلمه کلیدی init تعریف میشوند و وظیفه مقداردهی اولیه متغیر های struct را دارند.
به طور کلی دو کاربرد رایج دارند:
struct Phone {
var name: String
init() {
name = "iPhone 12 Pro Max"
}
}
var somePhone = Phone()
print(somePhone.name)
somePhone.name = "iPhone 8 Plus"
print(somePhone.name)
خروجی:
iPhone 12 Pro Max
iPhone 8 Plus
در این روش مقدار متغیر ها بر اساس پارامتر هایی که به init میدهیم تعیین میشود.
struct Apple {
var desc: String
init(iphone: String) {
desc = "\(iphone) is one of apple phones"
}
init(ipad: String) {
desc = "\(ipad) is good for children"
}
}
let phone = Apple(iphone: "iPhone 12")
print(phone.desc)
let tablet = Apple(ipad: "iPad mini")
print(tablet.desc)
خروجی:
iPhone 12 is one of apple phones
iPad mini is good for children
یکی از تفاوت های مهم بین struct و class این است که struct ها value type هستند.
یعنی وقتی یک struct را در متغیر دیگری کپی میکنیم، در واقع یک نسخه جدید از آن ساخته میشود.
struct User {
var name: String
}
var user1 = User(name: "Ali")
var user2 = user1
user2.name = "Sara"
print(user1.name)
print(user2.name)
خروجی:
Ali
Sara
تا الان متغیر هایی که داخل struct تعریف کردیم مقدارشان به صورت مستقیم ذخیره میشد. اما گاهی اوقات لازم داریم مقدار یک متغیر بر اساس متغیر های دیگر محاسبه شود.
به چنین متغیر هایی Computed Property گفته میشود.
struct Rectangle {
var width: Double
var height: Double
var area: Double {
return width * height
}
}
let rect = Rectangle(
width: 10,
height: 5
)
print(rect.area)
خروجی:
50
به صورت پیش فرض توابع داخل struct نمیتوانند مقدار متغیر های struct را تغییر دهند.
اگر بخواهیم داخل یک تابع مقدار متغیر ها را تغییر دهیم باید قبل از تابع از کلمه mutating استفاده کنیم.
struct Counter {
var number: Int
mutating func increase() {
number += 1
}
}
var counter = Counter(number: 0)
counter.increase()
print(counter.number)
خروجی:
1
mutating را ننویسیم اجازه تغییر مقدار متغیر های struct داخل تابع را نداریم.گاهی اوقات لازم داریم یک متغیر یا تابع متعلق به خود struct باشد نه instance های آن.
در چنین حالتی از کلمه static استفاده میکنیم.
struct Website {
static var siteName = "Swift Academy"
}
print(Website.siteName)
خروجی:
Swift Academy