0Pricing
Learn Rust Coding · Ders

Özellikleri Tanımlama ve Uygulama

Diğer dillerdeki arayüzlere benzeyen özelliklerle farklı türler arasında ortak davranış tanımlamada ustalaşın.

Özellikleri Tanımlama ve Uygulama, CoddyKit'te ücretsiz bir Learn Rust Coding dersidir. Bu, 3 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Learn Rust Coding öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Learn Rust Coding kursu toplamda 3 dersten oluşur.

Rust'ta Özellikler Nedir?

Rust'ta özellikler, farklı türler arasında ortak davranış tanımlamanın güçlü bir yoludur. Bunları diğer dillerdeki arayüzler gibi düşünebilirsiniz.

Bir özellik, Rust'a belirli bir türün belirli işlevlere sahip olduğunu bildirir. Bir tür bir özelliği uyguluyorsa, bu tür o özellikte tanımlanan yöntemleri sağlıyor demektir.

  • Özellikler çok biçimliliği mümkün kılar: Farklı türlerle tek tip bir biçimde çalışmanızı sağlar.
  • Rust'ın tür sistemi ve güvenli soyutlamaları için temel öneme sahiptir.

İlk Özelliğinizi Bildirme

Bir özelliği trait anahtar sözcüğünü kullanarak tanımlarsınız. İçinde, onu uygulayan her türün sağlaması gereken yöntem imzalarını (adlar, parametreler ve dönüş türleri) listelersiniz.

Özetlenebilen öğeler için basit bir Summary özelliği tanımlayalım.

trait Summary {
  fn summarize(&self) -> String;
}

fn main() {
  // Traits are definitions, not directly executable.
  // We will implement and use them in later scenes!
  println!("Trait 'Summary' defined.");
}

Türler İçin Özellik Uygulama

Bir türün bir özelliği kullanmasını sağlamak için impl Trait for Type sözdizimini kullanırsınız. Ardından özellikte tanımlanan her yöntem için somut uygulamayı sağlarsınız.

Burada Summary özelliğini bir NewsArticle yapısı için uyguluyoruz.

trait Summary {
  fn summarize(&self) -> String;
}

struct NewsArticle {
  headline: String,
  location: String,
  author: String,
  content: String,
}

impl Summary for NewsArticle {
  fn summarize(&self) -> String {
    format!("{}, by {} ({})", self.headline, self.author, self.location)
  }
}

fn main() {
  let article = NewsArticle {
    headline: String::from("Penguins win Stanley Cup!"),
    location: String::from("Pittsburgh, PA"),
    author: String::from("Iceburgh"),
    content: String::from("The Pittsburgh Penguins have won..."),
  };

  println!("New article summary: {}", article.summarize());
}

Özellik Sınırlı İşlevleri Kullanma

Bir tür bir özelliği uyguladıktan sonra, bu özelliği uygulayan herhangi bir türü kabul eden işlevler yazabilirsiniz. Bu, esnek ve jenerik kod yazmanıza olanak tanır.

notify işlevi, Summary özelliğini uygulayan herhangi bir türü alabilir.

trait Summary {
  fn summarize(&self) -> String;
}

struct NewsArticle {
  headline: String,
  location: String,
  author: String,
  content: String,
}

impl Summary for NewsArticle {
  fn summarize(&self) -> String {
    format!("{}, by {} ({})", self.headline, self.author, self.location)
  }
}

struct Tweet {
  username: String,
  content: String,
  reply: bool,
  retweet: bool,
}

impl Summary for Tweet {
  fn summarize(&self) -> String {
    format!("{}: {}", self.username, self.content)
  }
}

fn notify(item: &impl Summary) { // impl Summary is syntax sugar for a trait bound
  println!("Breaking news! {}", item.summarize());
}

fn main() {
  let tweet = Tweet {
    username: String::from("horse_ebooks"),
    content: String::from("of course, as you probably already know, people"),
    reply: false,
    retweet: false,
  };

  let article = NewsArticle {
    headline: String::from("Rust is awesome!"),
    location: String::from("Internet"),
    author: String::from("Rustacean"),
    content: String::from("Rust's type system is amazing."),
  };

  notify(&tweet);
  notify(&article);
}

Varsayılan Davranışa Sahip Özellikler

Özellikler, yöntemleri için varsayılan uygulamalar da sağlayabilir. Bu, bir varsayılan uygulama sağlanmışsa türlerin her yöntemi uygulamak zorunda olmadığı anlamına gelir.

Türler varsayılan uygulamayı kullanmayı veya kendi mantıklarıyla üzerine yazmayı seçebilir.

trait Summary {
  fn summarize_author(&self) -> String; // New required method
  fn summarize(&self) -> String { // Default implementation
    format!("(Read more from {})", self.summarize_author())
  }
}

struct Tweet {
  username: String,
  content: String,
  reply: bool,
  retweet: bool,
}

impl Summary for Tweet {
  fn summarize_author(&self) -> String { // Must implement required method
    format!("@{}", self.username)
  }
  // We are using the default summarize() method here!
}

fn main() {
  let tweet = Tweet {
    username: String::from("dog_lover"),
    content: String::from("My dog is the best!"),
    reply: false,
    retweet: false,
  };

  println!("Tweet summary: {}", tweet.summarize());
}

Özelliklerle Jenerik İşlevler

Jenerik işlevler veya yapılar yazarken, bir jenerik tür parametresi olan T'nin belirli bir özelliği uygulaması gerektiğini belirtmek için özellik sınırlarını kullanabilirsiniz.

Bu, o özelliğe ait yöntemlerin T için kullanılabilir olmasını sağlar.

trait Displayable {
  fn display(&self);
}

struct Point<T> {
  x: T,
  y: T,
}

// Implement Displayable for Point<i32>
impl Displayable for Point<i32> {
  fn display(&self) {
    println!("Point: ({}, {})", self.x, self.y);
  }
}

// Generic function that works for any type T that implements Displayable
fn print_item<T: Displayable>(item: T) {
  item.display();
}

fn main() {
  let p = Point { x: 10, y: 20 };
  print_item(p);
  // This function only works for types that implement Displayable
  // let s = String::from("Hello");
  // print_item(s); // This would cause a compile-time error
}

Birden Çok Özellik Sınırını Birleştirme

Bazen bir jenerik türün birden fazla özelliği uygulaması gerekir. + operatörünü kullanarak birden çok özellik sınırı belirtebilirsiniz.

Daha karmaşık durumlarda, özellikle çok sayıda jenerik parametre olduğunda, where yan tümcesi okunabilirliği artırabilir.

use std::fmt::Debug;

trait Printable {
  fn print_info(&self);
}

struct Book {
  title: String,
  pages: u32,
}

impl Printable for Book {
  fn print_info(&self) {
    println!("Book: '{}' ({} pages)", self.title, self.pages);
  }
}

impl Debug for Book { // Book also implements Debug trait
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    write!(f, "Book {{ title: {}, pages: {} }}", self.title, self.pages)
  }
}

// A function that requires its argument to be both Printable and Debug
fn process_item<T: Printable + Debug>(item: T) {
  item.print_info();
  println!("Debug info: {:?}", item);
}

fn main() {
  let my_book = Book {
    title: String::from("The Rust Book"),
    pages: 600,
  };

  process_item(my_book);
}

`impl Trait` ile Tür Döndürme

impl Trait sözdizimi yalnızca işlev parametreleri için kullanılmaz; dönüş konumlarında da kullanılabilir. Bu, belirli bir özelliği uygulayan bir türü döndürmek istediğinizde, ancak türün tam somut türünü açıklamak istemediğinizde kullanışlıdır.

İşlev imzalarını basitleştirir ve API'nizi esnek tutar.

trait Greeter {
  fn greet(&self) -> String;
}

struct FriendlyGreeter;
impl Greeter for FriendlyGreeter {
  fn greet(&self) -> String {
    String::from("Hello there!")
  }
}

struct FormalGreeter;
impl Greeter for FormalGreeter {
  fn greet(&self) -> String {
    String::from("Greetings and salutations.")
  }
}

// This function returns *some* type that implements Greeter
// The caller doesn't need to know if it's FriendlyGreeter or FormalGreeter
fn get_greeter(formal: bool) -> impl Greeter {
  if formal {
    FormalGreeter
  } else {
    FriendlyGreeter
  }
}

fn main() {
  let casual_greet = get_greeter(false);
  println!("{}", casual_greet.greet());

  let formal_greet = get_greeter(true);
  println!("{}", formal_greet.greet());
}

Üst Özellikler Üzerine İnşa Etme

Bazen bir özellik mantıksal olarak başka bir özelliğe bağlı olabilir. Rust, üst özellikler tanımlamanıza olanak tanır; yani bir özellik, onu uygulayan her türün belirli başka bir özelliği de uygulamasını gerektirebilir.

Bu işlem trait SubTrait: SuperTrait sözdizimiyle yapılır. Bu, “X'i yapabiliyorsanız Y'yi de yapabilmelisiniz” demek gibidir.

trait Printable {
  fn print_content(&self);
}

// Debug is a supertrait of PrintableDebug
// Any type implementing PrintableDebug must also implement Debug
trait PrintableDebug: Printable + std::fmt::Debug {
  fn print_debug_and_content(&self) {
    self.print_content();
    println!("Debug info: {:?}", self);
  }
}

struct Item {
  id: u32,
  name: String,
}

impl Printable for Item {
  fn print_content(&self) {
    println!("Item ID: {}, Name: {}", self.id, self.name);
  }
}

impl std::fmt::Debug for Item {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    write!(f, "Item {{ id: {}, name: {} }}", self.id, self.name)
  }
}

// Now we can implement PrintableDebug because Item implements both Printable and Debug
impl PrintableDebug for Item {}

fn main() {
  let my_item = Item {
    id: 101,
    name: String::from("Widget A"),
  };
  my_item.print_debug_and_content();
}

Özellik Bilginizi Sınayın

Aşağıdaki Rust kod parçacığını inceleyin. Aşağıdaki ifadelerden hangisi özellikler ve özellik sınırları hakkında DOĞRUDUR?

Özellikler: Davranış Araç Setiniz

Rust'ın güçlü özellik sistemini inceledik!

  • Özellikler, bir türün uygulayabileceği bir yöntemler kümesi tanımlar ve arayüzler gibi davranır.
  • Özellikleri belirli türler için impl Trait for Type kullanarak uygularsınız.
  • Özellik sınırları (T: Trait), jenerik işlevlerin ve yapıların gerekli özelliği uygulayan herhangi bir türle çalışmasına olanak tanır.
  • Özellikler varsayılan uygulamalara sahip olabilir; birden çok özellik sınırı (T: Trait1 + Trait2) belirtebilir veya üst özellikler kullanabilirsiniz.
  • impl Trait, somut türleri gizlemek için dönüş konumlarında da kullanılabilir.

Özellikler, esnek, yeniden kullanılabilir ve güvenli Rust kodu yazmanın temelidir!

Sıkça Sorulan Sorular

“Özellikleri Tanımlama ve Uygulama” dersi ücretsiz mi?

Evet — “Özellikleri Tanımlama ve Uygulama” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Learn Rust Coding kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Learn Rust Coding kursu toplamda 3 dersten oluşur.

“Özellikleri Tanımlama ve Uygulama” dersinde ne öğreneceğim?

Diğer dillerdeki arayüzlere benzeyen özelliklerle farklı türler arasında ortak davranış tanımlamada ustalaşın. Learn Rust Coding ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Learn Rust Coding öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Learn Rust Coding, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 3 dersinin 2. dersidir.

“Özellikleri Tanımlama ve Uygulama” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Learn Rust Coding dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Learn Rust Coding dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Rust'ta Genel Kod Yazma
  2. Özellikleri Tanımlama ve Uygulama
  3. İleri Düzey Özellik Kullanımı: İlişkili Türler
← Learn Rust Coding Sayfasına Dön