02open 25 min

Syntax and structure: from packages and methods to modules and impl

Map familiar Go file and type organization onto Rust modules, structs, and impl blocks.

by the end of this lesson you can

  • Uses Rust struct field syntax
  • Puts behavior inside an impl block
  • Chooses &self or &mut self intentionally

Overview

Go developers already know compiled-language structure, but Rust arranges code differently. The goal here is not to translate token by token, but to recognize how packages, functions, structs, and methods map into modules, free functions, structs, and impl blocks.

In Go, you often

organize code around packages, exported names, structs, and methods attached to concrete types.

In Rust, the common pattern is

to organize by modules, structs, enums, free functions, and impl blocks that group associated behavior.

why this difference matters

This is where Rust starts to feel legible. Once the structure clicks, later concepts have a clearer home.

Go

type User struct {
    Name string
}

func (u User) Greet() string {
    return "hi " + u.Name
}

Rust

struct User {
    name: String,
}

impl User {
    fn greet(&self) -> String {
        format!("hi {}", self.name)
    }
}

Deeper comparison

Go version

package config

type Settings struct {
    Debug bool
}

func Load() (Settings, error) {
    return Settings{}, nil
}

Rust version

mod config {
    pub struct Settings {
        pub debug: bool,
    }

    pub fn load() -> Result<Settings, ConfigError> {
        Ok(Settings { debug: false })
    }
}

Reflect

What is easier to scan once you stop looking for Go package conventions and start reading Rust in terms of modules and impl blocks?

what a strong answer notices

A strong answer mentions clearer grouping of data, behavior, visibility, and fallible constructors or loaders.

Rewrite

Rewrite this Go struct-plus-method shape into Rust using a struct and impl block.

Rewrite this Go

type Counter struct {
    Value int
}

func (c *Counter) Inc() {
    c.Value++
}

what good looks like

  • Uses Rust struct field syntax
  • Puts behavior inside an impl block
  • Chooses &self or &mut self intentionally

Practice

Design a small Rust module for request validation starting from a Go mental model of package, struct, and method.

success criteria

  • Uses a module boundary intentionally
  • Separates data from associated behavior cleanly
  • Explains where visibility should be public or private

Common mistakes

  • Looking for a one-to-one package-to-module translation everywhere.
  • Treating impl as just method syntax instead of a code-organization tool.
  • Ignoring ownership when translating pointer-receiver habits from Go.

takeaways

  • This is where Rust starts to feel legible. Once the structure clicks, later concepts have a clearer home.
  • A strong answer mentions clearer grouping of data, behavior, visibility, and fallible constructors or loaders.
  • Uses a module boundary intentionally