Using Interface Types
Part of the Logic & Flow section of Coddy's GO journey — lesson 15 of 68.
Now that you know how to define and implement interfaces, let's explore how to actually use interface types in your code. The real power of interfaces comes from being able to create variables and function parameters of an interface type.
You can declare a variable of an interface type and assign any value to it, as long as that value's type implements the interface. Here is a complete example — from declaring the interface, to implementing it, to using it:
type Shaper interface {
Area() float64
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
var shape Shaper
shape = Circle{Radius: 5.0}
fmt.Println(shape.Area()) // Works perfectly!This becomes especially powerful when writing functions. Instead of writing separate functions for each concrete type, you can write one function that accepts the interface type:
func printArea(s Shaper) {
fmt.Printf("Area: %.2f\n", s.Area())
}This single function can now work with any type that implements the Shaper interface - whether it's a Circle, Rectangle, or any other shape you create in the future. The function doesn't need to know the specific type; it only cares that the type can calculate its area.
This approach makes your code more flexible and reusable, allowing you to write functions that work with multiple types through their shared behaviors.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
Challenge
EasyIn this challenge, you'll practice using interface types by creating a drawing application that can work with different geometric shapes. You'll create a function that accepts an interface type as a parameter, demonstrating how interfaces make your code flexible and reusable.
You will receive three inputs:
- A string representing the shape type (either
"circle"or"rectangle") - A string representing the first dimension (radius for circle, width for rectangle)
- A string representing the second dimension (not used for circle, height for rectangle)
Your task is to:
- Define a
Shapeinterface with one method signature:Area()that returns a float64 - Define a
Circlestruct with aRadiusfield (float64) - Define a
Rectanglestruct withWidthandHeightfields (both float64) - Implement the
Area()method for both structs:- Circle area: 3.14159 × radius × radius
- Rectangle area: width × height
- Create a function called
printShapeInfothat takes aShapeinterface as a parameter and prints the area in the format:"Area: [area]" - Based on the input shape type, create the appropriate shape instance and call
printShapeInfowith it
The area should be displayed with up to 7 decimal places, but trailing zeros should be removed (e.g., 15.70796 instead of 15.70796000). This challenge demonstrates how a single function can work with multiple types through their shared interface, making your code more flexible and maintainable.
Cheat sheet
You can declare variables of an interface type and assign any value that implements the interface:
var shape Shaper
shape = Circle{Radius: 5.0}
fmt.Println(shape.Area()) // Works perfectly!Functions can accept interface types as parameters, making them work with any type that implements the interface:
func printArea(s Shaper) {
fmt.Printf("Area: %.2f\n", s.Area())
}This approach makes code more flexible and reusable by allowing functions to work with multiple types through their shared behaviors.
Try it yourself
package main
import (
"fmt"
"strconv"
)
// TODO: Define Shape interface with an Area() float64 method
// TODO: Define Circle struct with a Radius field (float64)
// TODO: Define Rectangle struct with Width and Height fields (float64)
// TODO: Implement Area() method for Circle (use 3.14159 for pi)
// TODO: Implement Area() method for Rectangle
// TODO: Define printShapeInfo function that accepts a Shape and prints its area
func main() {
// Read input
var shapeType string
var dimension1 string
var dimension2 string
fmt.Scanln(&shapeType)
fmt.Scanln(&dimension1)
fmt.Scanln(&dimension2)
// Convert string inputs to float64
dim1, _ := strconv.ParseFloat(dimension1, 64)
dim2, _ := strconv.ParseFloat(dimension2, 64)
// TODO: Declare a Shape variable
// TODO: If shapeType is "circle", assign a Circle using dim1 as Radius
// TODO: If shapeType is "rectangle", assign a Rectangle using dim1 as Width and dim2 as Height
// TODO: Call printShapeInfo with the created shape
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Advanced Control Flow
Switch with `fallthrough`Breaking from Nested LoopsContinuing a Specific LoopThe `goto` StatementRecap - Advanced Loop Control4Project: Simple Task List
Project SetupAdding a Task2Structs and Methods
Defining Methods on StructsValue ReceiversPointer ReceiversChoosing ReceiversMethods vs FunctionsRecap - Struct Behavior5Maps In-Depth
Maps of StructsPointers as Map ValuesTesting for Nil MapsComparing MapsRecap - Word Frequency Counter3Interfaces (The Basics)
What is an Interface?Defining an InterfaceImplementing an InterfaceUsing Interface TypesEmpty InterfaceType AssertionsType SwitchRecap - Shapes and Behaviors