Swift হল Apple-এর প্রোগ্রামিং ভাষা যা Objective-C-এর শক্তিকে আধুনিক ভাষার নিরাপত্তার সাথে একত্রিত করে। অন্যান্য অনেক ভাষার থেকে ভিন্ন, Swift অনন্য কাঠামো সরবরাহ করে: স্বয়ংক্রিয় কপি সহ মান প্রকার, কম্পাইলার-স্তরের বিচ্ছিন্নতা সহ Actors, সম্পত্তির যুক্তি পুনর্ব্যবহারের জন্য Property Wrappers এবং শাস্ত্রীয় উত্তরাধিকারের বিকল্প হিসেবে প্রোটোকল ওরিয়েন্টেড প্রোগ্রামিং। Apple Swift ডকুমেন্টেশন অনুসারে, এই বৈশিষ্ট্যগুলি কোডকে নিরাপদ এবং আরও দক্ষ করে তোলে।
মূল বিষয়
Swift-এ, struct একটি মান প্রকার, যখন class একটি রেফারেন্স প্রকার। এই মৌলিক পার্থক্য অ্যাসাইনমেন্ট, ফাংশনে পাস এবং মেমরি ব্যবস্থাপনার সময় আচরণ নির্ধারণ করে। প্রতিটি অ্যাসাইনমেন্টে Struct সম্পূর্ণরূপে কপি হয়, class রেফারেন্স দ্বারা পাস হয় — শুধুমাত্র হিপ অবজেক্টের পয়েন্টার কপি হয়।
Struct স্বয়ংক্রিয়ভাবে মান শব্দার্থ প্রয়োগ করে — প্রতিটি ইন্সট্যান্স স্বাধীন। Struct-এর সম্পত্তির পরিবর্তন শুধুমাত্র var-এর মাধ্যমে সম্ভব, এবং সম্পত্তি পরিবর্তনকারী পদ্ধতিগুলিকে mutating চিহ্নিত করতে হবে। Struct উত্তরাধিকার সমর্থন করে না তবে প্রোটোকল মেনে চলতে পারে। Swift-এর স্ট্যান্ডার্ড লাইব্রেরি String, Array, Dictionary, Int, Bool-এর জন্য struct ব্যবহার করে — সব মৌলিক প্রকারই মান প্রকার।
struct User {
let id: Int
var name: String
mutating func updateName(_ newName: String) {
name = newName
}
}
var user1 = User(id: 1, name: "Alice")
var user2 = user1
user2.updateName("Bob")
// user1.name === "Alice", user2.name === "Bob"
// সম্পূর্ণ কপি — স্বাধীন ইন্সট্যান্স
Class হিপে সংরক্ষিত হয় এবং রেফারেন্স সমতা সমর্থন করে। একাধিক ভেরিয়েবল একই অবজেক্টকে রেফারেন্স করতে পারে, একটি রেফারেন্সের মাধ্যমে পরিবর্তন অন্য সবগুলিতে দৃশ্যমান। Class উত্তরাধিকার সমর্থন করে, পদ্ধতি ওভাররাইডিং (override) অনুমতি দেয়, সম্পদ পরিষ্কারের জন্য deinit আছে। Swift-এ, struct-এর তুলনায় class কম ব্যবহৃত হয় — Apple struct দিয়ে শুরু করার এবং শুধুমাত্র উত্তরাধিকার বা রেফারেন্স শব্দার্থের প্রয়োজন হলে class-এ স্যুইচ করার পরামর্শ দেয়।
class Car {
let model: String
var speed: Int
init(model: String, speed: Int) {
self.model = model
self.speed = speed
}
func accelerate(_ amount: Int) {
speed += amount
}
}
let car1 = Car(model: "Tesla", speed: 0)
let car2 = car1
car2.accelerate(50)
// car1.speed === 50, car2.speed === 50
// একই রেফারেন্স — পরিবর্তন সর্বত্র দৃশ্যমান
struct এবং class-এর মধ্যে পছন্দ ডেটার শব্দার্থের উপর নির্ভর করে। কনফিগারেশন, ডেটা মডেল এবং অবস্থার জন্য struct ব্যবহার করুন — কপি করা নিরাপদ এবং অনুমানযোগ্য। পরিচয়বহুল বস্তুর (ব্যবহারকারী সেশন, ডাটাবেস সংযোগ) জন্য এবং উত্তরাধিকারের প্রয়োজন হলে class ব্যবহার করুন।
Actor একটি রেফারেন্স প্রকার যা তার পরিবর্তনীয় অবস্থাকে সমবর্তী অ্যাক্সেস থেকে রক্ষা করে। Swift কম্পাইলার গ্যারান্টি দেয় যে actor ভেরিয়েবলগুলি শুধুমাত্র একই actor কনটেক্সট থেকে অ্যাক্সেস করা যেতে পারে — বাইরের কোনো অ্যাক্সেস কম্পাইলেশন ত্রুটির কারণ হয়। এটি ম্যানুয়াল লক ছাড়াই ভাষা স্তরে ডেটা রেস প্রতিরোধ করে।
সব actor সম্পত্তি এবং পদ্ধতি ডিফল্টরূপে বিচ্ছিন্ন। বাইরে থেকে actor পদ্ধতি কল করার জন্য await প্রয়োজন — Swift এক্সিকিউশন actor-এ এবং ফিরে স্যুইচ করে। Actor অ্যাক্সেস ক্রমিকভাবে সিঙ্ক্রোনাইজ করে: বিভিন্ন টাস্ক থেকে অনুরোধগুলি সারিবদ্ধ হয়। এটি actor-এর ভিতরে সামঞ্জস্যপূর্ণ অবস্থা নিশ্চিত করে। নন-বিচ্ছিন্ন পদ্ধতি (nonisolated) await ছাড়া কল করা যেতে পারে কিন্তু পরিবর্তনীয় সম্পত্তি অ্যাক্সেস করতে পারে না।
actor BankAccount {
private var balance: Double
init(initialBalance: Double) {
balance = initialBalance
}
func deposit(amount: Double) {
balance += amount
}
func withdraw(amount: Double) throws {
guard balance >= amount else {
throw BankError.insufficientFunds
}
balance -= amount
}
nonisolated func accountInfo() -> String {
return "ব্যাংক অ্যাকাউন্ট"
}
}
let account = BankAccount(initialBalance: 1000)
await account.deposit(amount: 500)
// balance = 1500 — পারমাণবিক, রেস কন্ডিশন ছাড়া
Actor অবস্থা পরিচালক, ক্যাশ এবং নেটওয়ার্ক পরিষেবার জন্য দরকারী যেখানে একাধিক টাস্ক সমবর্তীভাবে ডেটা পড়ে এবং লেখে। NSLock বা DispatchQueue-এর মাধ্যমে ম্যানুয়াল সিঙ্ক্রোনাইজেশনের বিপরীতে, actor কম্পাইল সময়ে পরীক্ষা করা হয় — ভুল করা অসম্ভব। বিচ্ছিন্নতা ত্রুটিগুলি কম্পাইল সময়ে দেখা যায়, রানটাইমে নয়।
Property Wrapper একটি অ্যানোটেশন যা সম্পত্তির ঘোষণা পরিবর্তন না করেই এতে আচরণ যোগ করে। SwiftUI এবং Combine ভিউ অবস্থা পরিচালনার জন্য বিল্ট-ইন র্যাপার সরবরাহ করে। কম্পাইলার কোড জেনারেট করে যা সম্পত্তি অ্যাক্সেস মোড়ক করে, পর্যবেক্ষণ, সিঙ্ক্রোনাইজেশন বা রূপান্তর যুক্তি যোগ করে।
@Published ObservableObject মেনে চলা ক্লাসে স্বয়ংক্রিয়ভাবে পরিবর্তন প্রকাশ করতে ব্যবহৃত হয়। Combine সাবস্ক্রাইবাররা প্রতিটি আপডেটে বিজ্ঞপ্তি পায়। @State হল SwiftUI ভিউ-এর স্থানীয় অবস্থা। @State পরিবর্তিত হলে SwiftUI স্বয়ংক্রিয়ভাবে ভিউ পুনরায় রেন্ডার করে। @Binding ডেটার মালিকানা ছাড়াই প্যারেন্ট এবং চাইল্ড ভিউ-এর মধ্যে দ্বিমুখী সংযোগ তৈরি করে।
import SwiftUI
import Combine
@main
struct CounterApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class CounterViewModel: ObservableObject {
@Published var count: Int = 0
func increment() {
count += 1
}
}
struct ContentView: View {
@State private var greeting: String = "হ্যালো"
@StateObject private var viewModel = CounterViewModel()
var body: some View {
VStack {
CounterDisplay(count: $viewModel.count)
Text(greeting)
Button("বাড়ান", action: viewModel.increment)
}
}
}
struct CounterDisplay: View {
@Binding var count: Int
var body: some View {
Text("গণনা: \(count)")
}
}
কাস্টম Property Wrappers @propertyWrapper এবং wrappedValue ফিল্ড সহ একটি স্ট্রাক্টের মাধ্যমে তৈরি করা হয়। এটি যুক্তি পুনর্ব্যবহারের অনুমতি দেয়: বৈধতা, স্বাভাবিকীকরণ, UserDefaults সঞ্চয়। Property Wrappers বয়লারপ্লেট কোড উল্লেখযোগ্যভাবে হ্রাস করে এবং অ্যানোটেশনের মাধ্যমে ডেভেলপারের উদ্দেশ্য স্পষ্ট করে।
@propertyWrapper
struct Clamped<T: Comparable> {
private var value: T
let range: ClosedRange<T>
init(wrappedValue: T, range: ClosedRange<T>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
var wrappedValue: T {
get { value }
set { value = min(max(newValue, range.lowerBound), range.upperBound) }
}
}
struct Settings {
@Clamped(range: 0...100) var volume: Int = 50
}
var s = Settings()
s.volume = 150
// s.volume === 100 — মান স্বয়ংক্রিয়ভাবে সীমাবদ্ধ
Generics টাইপ নিরাপত্তা না হারিয়ে নমনীয় কোড লেখার জন্য Swift-এর একটি শক্তিশালী প্রক্রিয়া। জেনেরিক ফাংশন এবং প্রকারগুলি সীমাবদ্ধতা পূরণকারী যেকোনো প্রকারের সাথে কাজ করে। প্রোটোকল ওরিয়েন্টেড প্রোগ্রামিং (POP) একটি Swift প্যারাডাইম যেখানে protocol + extension শাস্ত্রীয় ক্লাস উত্তরাধিকার প্রতিস্থাপন করে, আচরণ কম্পোজিশন সরবরাহ করে।
Swift প্রোটোকল (where ক্লজ) দিয়ে জেনেরিক প্যারামিটার সীমাবদ্ধ করার অনুমতি দেয়। যুক্ত প্রকার সহ প্রোটোকল প্রোটোকলের জন্য জেনেরিক সমতুল্য: কংক্রিট প্রকার অনুবর্তনের সময় নির্ধারিত হয়। এটি টাইপ-নিরাপদ সংগ্রহ এবং অ্যালগরিদমের ভিত্তি। Swift-এর স্ট্যান্ডার্ড লাইব্রেরি সক্রিয়ভাবে জেনেরিক ব্যবহার করে: Array, Dictionary, Optional — সবই জেনেরিক প্রকার।
protocol Cacheable {
associatedtype Key: Hashable
associatedtype Value
func get(_ key: Key) -> Value?
mutating func set(_ value: Value, for key: Key)
}
struct MemoryCache<K: Hashable, V>: Cacheable {
private var storage: [K: V] = [:]
typealias Key = K
typealias Value = V
func get(_ key: K) -> V? {
return storage[key]
}
mutating func set(_ value: V, for key: K) {
storage[key] = value
}
}
func firstMatch<T: Equatable>(in array: [T], target: T) -> Int? {
for (index, item) in array.enumerated() {
if item == target {
return index
}
}
return nil
}
let numbers = [10, 20, 30, 40]
let index = firstMatch(in: numbers, target: 30)
// index === 2 — সব Equatable প্রকারের জন্য একটি জেনেরিক পদ্ধতি
প্রোটোকল extension POP-এর একটি মূল প্রক্রিয়া। extension-এ প্রোটোকল পদ্ধতির ডিফল্ট বাস্তবায়ন দেওয়া যেতে পারে। প্রোটোকল মেনে চলা প্রকারগুলি এই বাস্তবায়ন বিনামূল্যে পায় এবং প্রয়োজন হলে এটি ওভাররাইড করতে পারে। এটি ক্লাস উত্তরাধিকার ছাড়াই আচরণ পিরামিড তৈরি করতে দেয় — একাধিক উত্তরাধিকারের বিকল্প, যা Swift-এ উপলব্ধ নয়।
protocol Drivable {
var speed: Double { get set }
func drive()
}
extension Drivable {
func drive() {
if speed > 0 {
print("\(speed) কিমি/ঘন্টা গতিতে ড্রাইভিং")
}
}
}
struct Bicycle: Drivable {
var speed: Double = 15
}
struct Plane: Drivable {
var speed: Double = 900
func drive() {
print("\(speed) কিমি/ঘন্টা গতিতে উড়ান")
}
}
let bike = Bicycle()
bike.drive() // "15.0 কিমি/ঘন্টা গতিতে ড্রাইভিং" — ডিফল্ট
let plane = Plane()
plane.drive() // "900.0 কিমি/ঘন্টা গতিতে উড়ান" — ওভাররাইড
POP extension-এর সাথে একাধিক প্রোটোকলের মাধ্যমে কম্পোজিশন সক্ষম করে — একটি প্রকার একাধিক প্রোটোকল মেনে চলতে পারে, তাদের বাস্তবায়ন পেতে পারে। এটি একক ক্লাস উত্তরাধিকারের চেয়ে বেশি নমনীয় যেখানে সম্পূর্ণ পিরামিড স্থির। Swift-এর স্ট্যান্ডার্ড লাইব্রেরি POP-এর উপর নির্মিত: CustomStringConvertible, Equatable, Hashable, Codable — সবই extensions সহ প্রোটোকল।
Enum Swift-এ অন্যান্য ভাষার তুলনায় উল্লেখযোগ্যভাবে বেশি শক্তিশালী একটি কাঠামো। প্রতিটি কেসের যুক্ত মান থাকতে পারে — যেকোনো প্রকারের ডেটার একটি নির্বিচার সেট। extension এবং প্যাটার্ন ম্যাচিং-এর সংমিশ্রণে, enum অবস্থা, অপারেশন ফলাফল এবং সসীম অবস্থা মেশিন মডেলিংয়ের ভিত্তি হয়ে ওঠে।
যুক্ত মান প্রতিটি কেসকে অনন্য ডেটা সংরক্ষণ করতে দেয়। উদাহরণস্বরূপ, loading কেসে কোনো ডেটা নেই, success-এ ফলাফল রয়েছে, failure-এ ত্রুটি রয়েছে। switch-এর মাধ্যমে প্যাটার্ন ম্যাচিং যুক্ত মান বের করে এবং প্রতিটি কেস হ্যান্ডেল করে। কম্পাইলার সম্পূর্ণতা পরীক্ষা করে (exhaustive switch) — এটি ভুলে যাওয়া অবস্থা দূর করে।
enum NetworkResult<T> {
case loading
case success(T)
case failure(Error)
}
enum MediaFile {
case image(url: URL, width: Int, height: Int)
case video(url: URL, duration: Double)
case audio(url: URL, bitrate: Int)
}
func handle(_ result: NetworkResult<String>) {
switch result {
case .loading:
print("লোড হচ্ছে...")
case .success(let data):
print("প্রাপ্ত: \(data)")
case .failure(let error):
print("ত্রুটি: \(error.localizedDescription)")
}
}
let file = MediaFile.video(url: URL(string: "https://example.com/video.mp4")!, duration: 120)
if case .video(let url, let duration) = file {
print("ভিডিও \(url) সময়কাল \(duration)সে")
}
Swift enum-এর জন্য extension-এর মাধ্যমে পদ্ধতি, গণনাকৃত সম্পত্তি এবং প্রোটোকল অনুবর্তন যোগ করার অনুমতি দেয়। এটি মূল ঘোষণা পরিবর্তনের প্রয়োজন হয় না — কোড পরিষ্কার এবং মডিউলার থাকে। extension-এর পদ্ধতিগুলি যুক্ত মান নিয়ে কাজ করতে পারে, উদ্ভূত ডেটা গণনা করতে পারে এবং ব্যবসায়িক যুক্তি বাস্তবায়ন করতে পারে।
extension MediaFile {
var fileName: String {
switch self {
case .image(let url, _, _),
.video(let url, _),
.audio(let url, _):
return url.lastPathComponent
}
}
var description: String {
switch self {
case .image(_, let w, let h):
return "ছবি \(w)x\(h)"
case .video(_, let d):
return "ভিডিও \(d)সে"
case .audio(_, let b):
return "অডিও \(b) কেবিপিএস"
}
}
}
extension MediaFile: Equatable {
static func == (lhs: MediaFile, rhs: MediaFile) -> Bool {
return lhs.fileName == rhs.fileName
}
}
let files: [MediaFile] = [file]
files.forEach { print($0.description) }
// "ভিডিও 120.0s"
যুক্ত মান + extension সহ Enum হল Kotlin-এর সিল করা ক্লাস বা অন্যান্য ভাষার ডিসক্রিমিনেটেড ইউনিয়নের প্রতিস্থাপন। Swift এই সংমিশ্রণটি Result (স্ট্যান্ডার্ড লাইব্রেরির একটি আদর্শ প্রকার), Optional (Optional .none এবং .some সহ একটি enum) এবং SwiftUI-তে অবস্থা পরিচালনার জন্য ব্যবহার করে। প্যাটার্ন ম্যাচিং গ্যারান্টি দেয় যে সব অবস্থা হ্যান্ডেল করা হয়েছে — রানটাইম ত্রুটি অসম্ভব।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Struct — মান প্রকার, অ্যাসাইনমেন্টে কপি হয়, উত্তরাধিকার সমর্থন করে না। Class — রেফারেন্স প্রকার, রেফারেন্স দ্বারা পাস হয়, উত্তরাধিকার, deinit এবং পরিচয় পরীক্ষা (===) সমর্থন করে। Apple struct দিয়ে শুরু করার এবং শুধুমাত্র রেফারেন্স শব্দার্থের প্রয়োজন হলে class-এ স্যুইচ করার পরামর্শ দেয়।
Actor — থ্রেড-নিরাপদ রেফারেন্স প্রকার। কম্পাইলার বিভিন্ন কনটেক্সট থেকে পরিবর্তনীয় অবস্থায় সমবর্তী অ্যাক্সেস নিষিদ্ধ করে। Actor ব্যবহার করুন অবস্থা পরিচালক, ক্যাশ এবং পরিষেবাগুলির জন্য যা একাধিক টাস্ক দ্বারা অ্যাক্সেস করা হয়। Actor পদ্ধতি কল করতে await প্রয়োজন।
প্রধান: @State — স্থানীয় ভিউ অবস্থা; @Binding — মালিকানা ছাড়া ডেটা সংযোগ; @Published — ObservableObject-এ পরিবর্তন প্রকাশ; @StateObject — ObservableObject-এর মালিকানা; @EnvironmentObject — পরিবেশ থেকে নির্ভরতা। কাস্টম র্যাপার @propertyWrapper-এর মাধ্যমে তৈরি করা হয়।
POP — একটি প্যারাডাইম যেখানে protocol + extension ক্লাস উত্তরাধিকারের পরিবর্তে আচরণ সংজ্ঞায়িত করে। একটি প্রকার একাধিক প্রোটোকল মেনে চলে, তাদের বাস্তবায়ন বিনামূল্যে পায়। এটি উত্তরাধিকারের উপর কম্পোজিশন — বেশি নমনীয় এবং নিরাপদ। Swift-এর স্ট্যান্ডার্ড লাইব্রেরি (Equatable, Codable) POP-এর উপর নির্মিত।
Swift-এ enum যুক্ত মান সমর্থন করে — প্রতিটি কেস বিভিন্ন প্রকারের নির্বিচার ডেটা সংরক্ষণ করতে পারে। প্যাটার্ন ম্যাচিং (switch) এর সংমিশ্রণে, এটি অবস্থা, ত্রুটি এবং ডোমেইন-চালিত ডিজাইনের জন্য একটি শক্তিশালী মডেল সরবরাহ করে। Optional এবং Result হল যুক্ত মান সহ স্ট্যান্ডার্ড Swift enum।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।