Section 3/91 menit
3. Sintaks Dasar
3. Sintaks Dasar
Mendefinisikan Noncopyable Type
swift
// Tambahkan ~Copyable untuk opt-out dari default Copyable
struct FileHandle: ~Copyable {
private let descriptor: Int32
init?(path: String, flags: Int32 = O_RDONLY) {
let fd = Darwin.open(path, flags)
guard fd != -1 else { return nil }
self.descriptor = fd
}
// deinit DIJAMIN dipanggil tepat sekali — tidak ada double close
deinit {
Darwin.close(descriptor)
}
// 'consuming' method: menghabiskan ownership — instance tidak bisa dipakai lagi
consuming func close() {
// deinit akan memanggil Darwin.close setelah method ini selesai
// Bisa lakukan cleanup tambahan di sini
}
// 'borrowing' method: hanya membaca — tidak mengambil ownership
borrowing func read(count: Int) -> Data? {
var buffer = [UInt8](repeating: 0, count: count)
let bytesRead = Darwin.read(descriptor, &buffer, count)
guard bytesRead > 0 else { return nil }
return Data(buffer.prefix(bytesRead))
}
}
// Penggunaan:
func processFile() {
guard let file = FileHandle(path: "/tmp/data.txt") else { return }
let data = file.read(count: 1024) // borrow — file masih valid
process(data)
// let copy = file // ❌ ERROR: FileHandle tidak bisa di-copy
// file di-close otomatis saat keluar scope — TEPAT SEKALI
}
Move dengan consume
swift
func processFile() {
guard var file = FileHandle(path: "/tmp/data.txt") else { return }
// 'consume' memindahkan ownership secara eksplisit
let movedFile = consume file
// ❌ ERROR: file tidak bisa dipakai lagi setelah consume
// let data = file.read(count: 100)
// movedFile sekarang pemilik sah
let data = movedFile.read(count: 100)
// movedFile di-close saat keluar scope
}
Noncopyable Class
swift
// Class juga bisa noncopyable — mencegah reference sharing yang tidak diinginkan
final class UniqueConnection: ~Copyable {
private let socket: Int32
init(host: String, port: Int) {
// setup socket connection
self.socket = 0 // placeholder
}
deinit {
// disconnect dan cleanup
Darwin.close(socket)
}
func send(_ data: Data) {
// write ke socket
}
}
// Ownership sekarang jelas — tidak ada dua variabel yang bisa memegang koneksi yang sama
func handleRequest() {
let connection = UniqueConnection(host: "api.example.com", port: 443)
// let shared = connection // ❌ ERROR
connection.send(requestData)
// connection di-disconnect saat keluar scope
}