Soruya Genel Bakış
Rust'ta klasik OOP dillerindeki gibi yapılandırıcılar yoktur, ancak açılışlandırma ile tanımlarını gerçekleştiren associated fonksiyonlar (genellikle new) vardır. Associated fonksiyonlar, önceden belirlenmiş değerlerle yapı örnekleri oluşturmayı veya bellek tahsisatı gibi ek mantıkla yapı örnekleri oluşturmayı sağlar.
Sorun
Birçok kişi yalnızca new kullanmaya başlıyor, diğer fabrika yöntemi kalıplarını (örneğin, with_capacity) unutuyor veya yapıları yanlış bir şekilde (özellikle özel/genel alanlarla) başlatıyor, bu da invariance hatalarına yol açabilir.
Çözüm
new türünde bir associated fonksiyon impl üzerinden gerçekleştirilir, invariance ile nesne oluşturmanın tek giriş noktası olabilir. with_capacity gibi fonksiyonlar, bellek tahsisatını önceden yapma gibi ek olanaklar sunar.
Kod örneği:
pub struct MyBuffer { data: Vec<u8>, } impl MyBuffer { pub fn new() -> Self { MyBuffer { data: Vec::new() } } pub fn with_capacity(cap: usize) -> Self { MyBuffer { data: Vec::with_capacity(cap) } } }
Anahtar özellikler:
Eğer new gerçekleştirilmezse, Rust bunu otomatik olarak mı oluşturur?
Hayır. Herhangi bir otomatik new oluşturması yoktur. Eğer yöntem açıkça gerçekleştirilmemişse, mevcut olmayacaktır; her ne kadar yapı yalnızca genel alanlara sahip olsa bile.
new ile Default arasındaki temel fark nedir?
Default — yalnızca tipin Default'ı uyguladığı veya açıkça miras aldığı yerlerde çağrılabilen bir trait yapılandırıcısıdır. Genel algoritmalar için standarttır, ancak her zaman new ile örtüşmez.
new ve with_capacity metodlarını özel yapılarda kullanabilir miyiz?
Evet, metodlar genel veya özel yapılabilir, ancak özel bir yapı için genel bir yapılandırıcı oluşturmak, kullanıcıların bu yapının örneklerini modül dışında oluşturmalarına izin vermez.
İnvariantları olmayan açık bir yapı, tüm alanlar genel:
pub struct User { pub login: String, pub active: bool }
Artıları:
Eksileri:
Alanlar özel, yalnızca new ile oluşturulma, invariance sağlanmış:
pub struct User { login: String, active: bool } impl User { pub fn new(login: String) -> User { User { login, active: true } } }
Artıları:
Eksileri: