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