Section 5/111 menit
5. consuming — Transfer Ownership
5. consuming — Transfer Ownership
Konsep
consuming menyatakan: "Saya mengambil alih nilai ini. Caller tidak boleh menggunakannya lagi setelah memanggil fungsi ini."
swift
struct EncryptedData {
var ciphertext: [UInt8]
var nonce: [UInt8]
}
// 'consuming': mengambil alih EncryptedData
// Setelah ini, caller tidak bisa pakai variabelnya
func decrypt(_ data: consuming EncryptedData) -> Data {
// data adalah milik kita sekarang
let decrypted = performDecryption(data.ciphertext, nonce: data.nonce)
// data.ciphertext di-zero otomatis saat fungsi ini selesai (jika ~Copyable)
return Data(decrypted)
}
// Penggunaan:
var encrypted = EncryptedData(ciphertext: bytes, nonce: nonceBytes)
let plaintext = decrypt(encrypted) // encrypted di-consume di sini
// print(encrypted.ciphertext) // ❌ ERROR: 'encrypted' sudah di-consume
consuming Method
swift
struct RequestBuilder {
private var url: URL
private var headers: [String: String] = [:]
private var body: Data?
init(url: URL) { self.url = url }
// consuming method: return self yang sudah dimodifikasi
// Ini adalah Builder Pattern yang type-safe!
consuming func header(_ name: String, value: String) -> RequestBuilder {
var builder = self // consume self, buat salinan baru
builder.headers[name] = value
return builder
}
consuming func body(_ data: Data) -> RequestBuilder {
var builder = self
builder.body = data
return builder
}
// consuming: build menghabiskan builder
consuming func build() -> URLRequest {
var request = URLRequest(url: url)
headers.forEach { request.setValue($1, forHTTPHeaderField: $0) }
request.httpBody = body
return request
}
}
// Penggunaan — Builder Pattern yang ergonomis
let request = RequestBuilder(url: apiURL)
.header("Authorization", value: "Bearer \(token)")
.header("Content-Type", value: "application/json")
.body(requestBody)
.build()
// Setiap tahap consume builder sebelumnya dan buat yang baru
Consuming dalam Pipeline
swift
// Pipeline processing — setiap tahap mengambil alih dan mengembalikan nilai baru
struct ImageProcessor {
var pixelData: [UInt8]
var width: Int
var height: Int
consuming func resize(to size: CGSize) -> ImageProcessor {
var new = self
new.pixelData = performResize(new.pixelData, size: size)
new.width = Int(size.width)
new.height = Int(size.height)
return new
}
consuming func applyFilter(_ filter: ImageFilter) -> ImageProcessor {
var new = self
new.pixelData = filter.apply(to: new.pixelData)
return new
}
consuming func compress(quality: Double) -> Data {
return compressToJPEG(pixelData, quality: quality)
}
}
// Pipeline yang jelas — setiap tahap mengambil alih
let compressed = ImageProcessor(pixelData: rawPixels, width: 4000, height: 3000)
.resize(to: CGSize(width: 800, height: 600)) // consume original, hasilkan resized
.applyFilter(.sharpen) // consume resized, hasilkan filtered
.compress(quality: 0.85) // consume filtered, hasilkan Data