What Are Interfaces In Go?

4 minutes read

In Go, interfaces are a way to define a set of methods that a type must implement in order to satisfy the interface. This allows different types to be treated polymorphically, meaning that objects of different types can be used interchangeably if they satisfy the same interface. Interfaces in Go are implemented implicitly, meaning that a type does not need to explicitly declare that it implements an interface. Instead, as long as a type implements all the methods specified by an interface, it is considered to implement that interface. This makes interfaces in Go lightweight and flexible, allowing for greater code reuse and flexibility in designing applications.


How to define a variadic function that takes interfaces in Go?

In Go, you can define a variadic function that takes interfaces by using the empty interface type interface{}. This allows the function to accept values of any type.


Here's an example of how you can define a variadic function that takes interfaces:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package main

import (
    "fmt"
)

func myFunc(values ...interface{}) {
    for _, v := range values {
        fmt.Println(v)
    }
}

func main() {
    myFunc(1, "hello", true)
}


In this example, the myFunc function takes a variadic parameter values of type ...interface{}, which accepts values of any type. Inside the function, you can range over the values and print them out.


When calling the function myFunc in the main function, you can pass values of different types, such as an integer, string, and boolean, and the function will accept them because it takes interfaces.


Note that while using interfaces allows for flexibility in the types of values that can be passed to the function, it may lead to more complex code due to the need for type assertions or type switches when working with the values inside the function.


What is interface{} in Go?

In Go, interface{} is an empty interface type that can hold values of any type. It is similar to the concept of a generic type in other programming languages. Values of any type can be assigned to variables of type interface{}, making it a useful tool for working with unknown types or creating functions that can accept arguments of any type. However, using interface{} can make code less type safe and harder to understand, so it should be used judiciously.


How to define a method on an interface in Go?

In Go, interfaces are defined as a set of method signatures that a type must implement in order to be considered as implementing that interface. To define a method on an interface in Go, you simply declare a method signature in the interface definition.


Here is an example of how to define a method on an interface in Go:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
    "fmt"
)

type Shape interface {
    area() float64
}

type Circle struct {
    radius float64
}

func (c Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}

func main() {
    circle := Circle{radius: 5}
    
    var shape Shape
    shape = circle
    
    fmt.Println("Area of circle:", shape.area())
}


In this example, the Shape interface defines a method signature area() that must be implemented by any type that wants to be considered as implementing the Shape interface. The Circle type implements the Shape interface by defining a method with the signature area() that calculates the area of the circle.


What is a type assertion in Go?

A type assertion in Go is used to extract the dynamic type of an interface variable and assign it to another variable of a specified type. This is useful when working with interface variables that can hold values of different types.


For example, consider an interface variable v that can hold values of type int and string:

1
2
3
4
5
6
var v interface{}
v = 42

// Type assertion to extract the value as an int
i := v.(int)
fmt.Println(i) // Outputs: 42


If the interface variable does not hold the specified type, a panic will occur at runtime. To handle this, we can use a type switch:

1
2
3
4
5
6
7
8
switch val := v.(type) {
case int:
    fmt.Println("Value is an int:", val)
case string:
    fmt.Println("Value is a string:", val)
default:
    fmt.Println("Unknown type")
}



How to create a custom error type that satisfies the error interface in Go?

In Go, custom error types can be created by implementing the Error() method on a custom struct. This method should return a string that describes the error.


Here is an example of how to create a custom error type that satisfies the error interface in Go:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
	"fmt"
)

// CustomError is a custom error type that implements the error interface
type CustomError struct {
	Message string
	Code    int
}

// Error returns the error message as a string
func (e CustomError) Error() string {
	return e.Message
}

func main() {
	err := CustomError{Message: "Custom error message", Code: 500}
	fmt.Println(err.Error())
}


In this example, the CustomError struct has a Message field that holds the error message and a Code field that holds an error code. The Error() method is then implemented to return the error message as a string.


To use this custom error type, you can create an instance of CustomError and call the Error() method on it to get the error message. The CustomError type satisfies the error interface because it implements the Error() method.

Facebook Twitter LinkedIn Telegram Whatsapp