GO Import struct from another file [SOLVED]


Written by - Tuan Nguyen
Reviewed by - Deepak Prasad

In this tutorial we will learn how to import struct from another file or package in golang. We will demonstrate a step by step approach to help you understand from basics

When working with Go (also known as Golang), understanding how to effectively organize and access data structures across different files and packages is crucial. This involves key concepts such as structs, packages, imports, and visibility rules.

Key Concepts:

  1. Structs: In Go, a struct is a composite data type that groups together variables (fields) under a single name. Structs are used to create complex data types that represent real-world entities.
  2. Packages: Go code is organized into packages. A package is a collection of Go files in the same directory, and it serves as a namespace for organizing code. The package declaration at the start of a Go file determines to which package the file belongs.
  3. Imports: To use code (like structs, functions, etc.) from another package, you need to import it. The import statement is used to include the contents of one package inside another.
  4. Exported vs. Unexported Identifiers: In Go, whether a name is capitalized matters. Names that start with a capital letter are exported (visible and accessible outside the package), while names that start with a lowercase letter are unexported (only accessible within the package).
  5. Visibility Rules: Understanding visibility is key to using structs across different files and packages. An exported struct can be accessed from other packages, but its unexported fields cannot.

Steps to import struct from another file or package in Golang

Importing a struct from another file in Go involves a few steps. This guide, with a detailed code example, will walk you through the process step by step.

 

1. Understanding Package Structure in Go

In Go, code is organized into packages. A package is a collection of Go source files in the same directory that are compiled together. Functions, types, variables, and constants defined in one source file are visible to all other source files within the same package.

Example:

Consider two files: main.go and models.go. They should be in the same directory for simplicity, and this directory represents your package.

 

2. Defining a Struct in a Separate File

First, define a struct in a separate file (models.go).

models.go

package main

type User struct {
    Name string
    Age  int
}

In this example, we have a struct User with two fields: Name and Age.

 

3. Importing the Struct in Your Main File

Since models.go and main.go are in the same package (main), you don't need to import the User struct explicitly. You can directly use it in main.go.

main.go

package main

import "fmt"

func main() {
    user := User{Name: "John Doe", Age: 30}
    fmt.Println(user)
}

 

4. Organizing Code in Different Packages

For larger projects, you might want to organize your code into different packages.

Example Structure:

  • main.go (package main)
  • models/
    • user.go (package models)

user.go

package models

type User struct {
    Name string
    Age  int
}

 

5. Importing the Struct from a Different Package

To use the User struct from user.go in your main.go, you need to import the models package. Read about import declarations rule .

The import path for a package is the path relative to the GOPATH src directory, or the module path if you are using Go Modules (which is recommended in modern Go practices).

  • With GOPATH: If your project path is $GOPATH/src/github.com/your_username/your_project, the import path for the models package would be github.com/your_username/your_project/models.
  • With Go Modules: If you are using Go Modules, the import path is typically the module name followed by the package name. For example, if your module is declared as module github.com/your_username/your_project in go.mod, the import path for the models package remains the same: github.com/your_username/your_project/models.

If you are confused or not familiar with these terminologies then I would recommend you to read Getting started with GOLANG | Write your first GO Code

main.go

package main

import (
    "fmt"
    "path/to/your/models" // Replace with the actual path to the models package
)

func main() {
    user := models.User{Name: "Jane Doe", Age: 25} // Using the User struct from models package
    fmt.Println(user)
}

After importing, you use the package name as a namespace to access its exported identifiers. In this case, models.User refers to the User struct in the models package.

 

6. Understanding Visibility of Struct Fields and Methods

1. Exporting struct fields

In Go, visibility (or accessibility) of struct fields and other identifiers is controlled by their naming convention. This step is crucial for structuring your code, especially when working with multiple packages.

Exported Identifiers: These are accessible from other packages. An identifier is exported if it starts with an uppercase letter. For structs, this applies both to the struct type itself and to its fields.

type User struct {
    Name string  // exported
    Age  int     // exported
}

Here, both User, Name, and Age are exported and can be accessed from other packages.

Unexported Identifiers: These are only accessible within the same package. An identifier is unexported if it starts with a lowercase letter.

type user struct {
    name string  // unexported
    age  int     // unexported
}

In this case, user, name, and age are unexported and cannot be accessed directly from other packages.

2. Exporting struct methods

Often, you'll define methods on your structs. The visibility of these methods follows the same rules. An exported method can be called from other packages, while an unexported method cannot.

func (u User) DisplayName() string {
    return u.Name
}

func (u *user) setAge(newAge int) {
    u.age = newAge
}

DisplayName is an exported method and can be called from other packages, whereas setAge is unexported and cannot.

Consider a scenario where you have a User struct in a models package, and you want to use it in your main package.

models/user.go:

package models

type User struct {
    Name string  // Exported: accessible from main
    age  int     // Unexported: not accessible from main
}

func (u *User) SetAge(newAge int) {
    u.age = newAge  // manipulating an unexported field within the package
}

main.go:

package main

import (
    "fmt"
    "github.com/your_username/your_project/models"
)

func main() {
    user := models.User{Name: "Jane Doe"}
    user.SetAge(25)  // valid: calling an exported method
    fmt.Println(user.Name)  // valid: accessing an exported field
    // fmt.Println(user.age)  // invalid: age is unexported
}

In this example, the main package can instantiate User, access its Name field, and call the SetAge method, but it cannot directly access the age field for which we may get error:

unknown field 'age' in struct literal of type models.User

 

7. Handling Dependencies and Go Modules

If your project is a module (which is recommended for managing dependencies), you need to ensure your go.mod file is properly set up.

Example:

Run go mod init your-module-name in your project directory to create a go.mod file.

 

8. Compiling and Running Your Code

Finally, compile and run your code:

go build
./your-program-name

Replace your-program-name with the name of your compiled binary.

Summary

In Go, importing a struct from another package is a fundamental aspect of modular programming, enhancing code organization and reusability. This process involves defining structs in a separate file or package, typically under a structured directory hierarchy. Structs are made accessible to other packages through exporting (naming with an uppercase first letter). The import statement is used in the receiving file, specifying the package path relative to the GOPATH or Go Modules. Proper understanding of package structure, visibility rules (exported vs. unexported identifiers), and the import path is crucial for effective cross-package struct usage in Go, ensuring a clean and maintainable codebase.

 

Views: 171

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on LinkedIn.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment