Monday, 25 August 2025

GOLANG receiver vs regular function


Rule of thumb:

 If the behavior is intrinsically tied to a type → use a method receiver.

If it’s more of a package-level operation or helper → use a regular function.



package xfile

// xfile/file.go

package xfile


import (

"io"

"os"

)


type File struct {

Path string

Data []byte

}


func New(path string) *File {

return &File{Path: path}

}


// Pointer receiver: mutates f.Data

func (f *File) Load() error {

b, err := os.ReadFile(f.Path)

if err != nil {

return err

}

f.Data = b

return nil

}


func (f *File) Save() error {

return os.WriteFile(f.Path, f.Data, 0o644)

}


// Package-level helper: not tied to one File instance

func CopyFile(src, dst string) error {

in, err := os.Open(src)

if err != nil {

return err

}

defer in.Close()


out, err := os.Create(dst)

if err != nil {

return err

}

defer func() { _ = out.Close() }()


if _, err = io.Copy(out, in); err != nil {

return err

}

return out.Sync()

}


main.go

package main


import (

"fmt"


"github.com/you/project/xfile"

)


func main() {

// Using a constructor (preferred when there’s setup)

f := xfile.New("test.txt")


// Or: f := &xfile.File{Path: "test.txt"}

// Or: f := new(xfile.File); f.Path = "test.txt"


if err := f.Load(); err != nil {

fmt.Println("load error:", err)

return

}


// mutate and save

f.Data = append(f.Data, []byte("\nhello\n")...)

if err := f.Save(); err != nil {

fmt.Println("save error:", err)

return

}


// Use package-level utility

if err := xfile.CopyFile("test.txt", "test_copy.txt"); err != nil {

fmt.Println("copy error:", err)

}

}

No comments:

Post a Comment