Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 1

Defining Traits with Method Signatures

Recommended resources

Welcome to your first lesson on Rust traits! Given your goal to learn the fundamentals, we'll start at the very beginning. This course is designed to be fast-paced and practical, fitting into your limited time.

In this lesson, we will focus on the first step: learning how to define a trait with a specific method signature. This is the foundation upon which all other trait concepts are built. By the end of this ~20-minute session, you'll be able to create your own "contracts" for behavior in Rust.

What is a Trait?

Before we write any code, let's build a clear mental model. In Rust, a trait is a way to define shared behavior. Think of it as a contract or a set of rules. Any type (like a struct or an enum) that wants to claim it has this behavior must agree to fulfill the contract by implementing the required methods.

To explore this idea further, please read the short introductory section of the following article. The author uses a great analogy of a driving school to explain the concept.

Understanding Rust Traits: For a beginner | by Mir luqman

The article 'Understanding Rust Traits: For a beginner' provides a simple and effective analogy for understanding what a trait is.

Read the section titled 'What Even Is a Trait?'.

This "contract" is what allows Rust to group different types together based on what they can do, rather than what they are.


Defining a Trait: The Syntax

Now that we have the concept down, let's look at the syntax. Defining a trait is straightforward. You use the trait keyword, give your trait a name, and then list the method signatures that any implementing type must provide.

A method signature defines the function's name, its parameters, and its return type, but it does not include the function's body (the code that actually runs).

Watch this short video segment to see how a Summary trait is defined. Pay close attention to the syntax used.

Traits in Rust

This clip from the 'Traits in Rust' video by Let's Get Rusty clearly demonstrates the syntax for defining a trait and its method signature.

Watch from 00:53 to 01:52. Focus on how the Summary trait is declared and how the summarize method signature is written, especially the use of the semicolon at the end.

As you saw in the video, the basic structure looks like this:

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

Let's break this down piece by piece. The following resource provides an excellent, commented explanation of this exact code.

Understanding Rust Traits: For a beginner | by Mir luqman

This section from 'Understanding Rust Traits: For a beginner' provides a commented breakdown of the trait definition syntax.

Find the 'Full code snippet' near the end of the article. Focus your attention on 'STEP 1: Define the Trait (Contract)' and read the comments that break down the summarize method signature.

To summarize the key components of a method signature within a trait:

  • fn: The keyword used to declare a function.
  • method_name: The name of the method (e.g., summarize).
  • (&self): A required parameter for almost all trait methods. It's a reference to the instance of the type that the method is being called on. This is how the method can access the data within the struct.
  • -> ReturnType: Specifies the data type that the method will return (e.g., -> String). If the method doesn't return anything, you omit this part.
  • ;: This is crucial. The semicolon at the end indicates that you are only defining the method signature. You are stating a requirement, not providing the implementation.
Test your understanding!

Your task is to define a trait that represents objects that can be drawn on a screen.

  1. Define a trait named Drawable.
  2. Inside this trait, specify a single method signature for a method named draw.
  3. The draw method should take a reference to self and should not return any value.

How would you write this code?

Show answer
trait Drawable {
    fn draw(&self);
}

Notice there is no -> ReturnType because the function doesn't return a value. The semicolon at the end is still required to signify it's a signature without a body.


Conclusion

In this lesson, you've taken the first crucial step in mastering Rust traits. You learned what a trait is conceptually and, most importantly, how to write the code to define one.

Here are the key takeaways:

  • Traits are contracts: They define a set of methods that a type must implement, establishing a standard for shared behavior.
  • Use the trait keyword: This is how you begin a trait definition.
  • Define method signatures, not bodies: Inside the trait block, you specify what methods are required, including their parameters and return types, ending each signature with a semicolon (;).

Now that you know how to create the "rules," the next logical step is to learn how to make your types follow them. In the next lesson, we will focus on implementing a custom trait for a struct type, bringing our abstract contract to life with concrete code.