Oliver's Blog
  • 🤩Welcome!
  • Projects
    • RISC Game
    • Mini Amazon
    • HTTP Caching Proxy
    • Course Enrollment App
    • Fitness Tracker App
    • Voice Shopping Assistant
    • Graphics Town
  • Algo
    • Binary Search
      • Classical Binary Search
      • First Position of Target
      • Last Position of Target
      • Guess Number Higher or Lower
      • Search in a Big Sorted Array
      • Total Occurrence of Target
      • First Bad Version
      • Find Minimum in Rotated Sorted Array
      • Maximum Number in Mountain Sequence
      • Search a 2D Matrix
      • Search a 2D Matrix II
      • Search for a Range
      • Smallest Rectangle Enclosing Black Pixels
      • Find Peak Element
      • Search in Rotated Sorted Array
      • Wood Cut
      • Find the Duplicate Number
      • Sqrt(x) II
      • Maximum Average Subarray II
      • Copy Books
      • How Many Problem Can I Accept
    • Linked List
      • Insert Node in Sorted Linked List
      • Merge Two Sorted Lists
      • Merge K Sorted Lists
      • LRU Cache
      • Reverse Linked List II
      • Copy List with Random Pointer
      • Reverse Nodes in k-Group
      • Add Two Numbers
      • Swap Nodes in Pairs
      • Rotate List
      • Linked List Cycle
      • Linked List Cycle II
      • Intersection of Two Linked Lists
      • Remove Linked List Elements
      • Reverse Linked List
      • Delete Node in a Linked List
      • Odd Even Linked List
      • Partition List
    • Recursion Basics
      • Fibonacci
      • Double Factorial
      • Reverse Order Storage
      • Linked List Weighted Sum In Reverse Order
    • Binary Tree
      • 1. Traversal
        • Binary Tree Preorder Traversal
        • Binary Tree Inorder Traversal
        • Binary Tree Postorder Traversal
        • Construct Binary Tree from Inorder and Postorder Traversal
        • Minimum Depth of Binary Tree
        • Find Leaves of Binary Tree
        • Reconstruct Itinerary
      • 2. Classical Questions
        • Maximum Depth of Binary Tree
        • Average of Levels in Binary Tree
        • Binary Tree Leaf Sum
        • Invert Binary Tree
        • Binary Tree Path Sum
        • Binary Tree Path Sum II
        • Binary Tree Path Sum III
        • Clone Binary Tree
        • Sum Root to Leaf Numbers
        • Binary Tree Level Sum
        • Binary Tree Paths
      • 3. Binary Search Tree
        • Insert Node in a Binary Search Tree
        • Remove Node in Binary Search Tree
        • Validate Binary Search Tree
        • Trim a Binary Search Tree
        • Search Range in Binary Search Tree
        • Inorder Successor in BST
        • Binary Search Tree Iterator
        • Recover Binary Search Tree
      • 4. Divide and Conquer
        • Balanced Binary Tree
        • Minimum Subtree
        • Subtree with Maximum Average
        • Maximum Subtree
        • Lowest Common Ancestor of a Binary Tree
        • Lowest Common Ancestor II
        • Lowest Common Ancestor III
        • Binary Tree Maximum Path Sum II
        • Binary Tree Maximum Path Sum
        • Path Sum III
      • Convert Sorted Array to Binary Search Tree
      • Path Sum
      • Lowest Common Ancestor of a Binary Search Tree
      • Sum of Left Leaves
      • Minimum Absolute Difference in BST
      • Minimum Distance Between BST Nodes
      • Convert Sorted List to Binary Search Tree
      • Range Sum of BST
      • Kth Smallest Element in a BST
      • Find Largest Value in Each Tree Row
    • Sorting
      • Sort Integers
      • Merge Two Sorted Arrays
      • Reverse Pair
      • Sort List
      • Partition Array
      • Sort Colors
      • Kth Largest Element
      • Multi-keyword Sort
    • Two Pointers
      • Window Sum
      • Two Sum - Difference equals to target
      • Valid Palindrome
      • Remove Duplicates from Sorted Array
      • Recover Rotated Sorted Array
      • Two Sum II - Input array is sorted
      • Two Sum - Unique pairs
      • Two Sum - Closest to target
    • Queue & Stack
      • Implement Queue by Interface
      • Implement Stack
      • Implement Queue by Two Stacks
      • Implement Stack by Two Queues
      • Binary Tree Level Order Traversal
      • Valid Parentheses
      • Min Stack
      • Largest Rectangle in Histogram
      • Evaluate Reverse Polish Notation
      • Implement Queue by Linked List II
      • Basic Calculator II
      • Moving Average from Data Stream
      • Reveal Cards In Increasing Order
      • Longest Valid Parentheses
    • Hash Table
      • Rehashing
      • Valid Anagram
      • Two Sum
      • Contiguous Array
      • Anagrams
      • Remove Duplicate Numbers in Array
      • Friendship Service
    • Heap & Priority Queue
      • Heapify
      • Top k Largest Numbers II
      • K Closest Points
      • Kth Smallest Number in Sorted Matrix
      • Find Median from Data Stream
      • Sliding Window Median
      • Trapping Rain Water II
      • High Five
    • BFS
      • 1. BFS in Binary Tree
        • Check Full Binary Tree
        • Binary Tree Level Order Traversal II
        • Binary Tree Maximum Path Sum II
        • Convert Binary Tree to Linked Lists by Depth
      • 2. Connected Graph & Topologic Sorting
        • Search Graph Nodes
        • Graph Valid Tree
        • Connected Component in Undirected Graph
        • Topological Sorting
        • Course Schedule
        • Course Schedule II
        • Sequence Reconstruction
        • Clone Graph
        • Alien Dictionary
    • Array
      • Remove Element
      • Search Insert Position
      • Maximum Subarray
      • Plus One
      • Merge Sorted Array
      • Pascal's Triangle
      • Pascal's Triangle II
      • Best Time to Buy and Sell Stock
      • Best Time to Buy and Sell Stock II
      • Majority Element
      • Contains Duplicate
      • Contains Duplicate II
      • Summary Ranges
      • Missing Number
      • Move Zeroes
      • Third Maximum Number
      • Binary Search
      • Pairs of Songs With Total Durations Divisible by 60
      • 3Sum
      • Median of Two Sorted Arrays
      • Running Sum of 1d Array
      • Container With Most Water
    • String
      • Longest Substring Without Repeating Characters
      • Roman to Integer
      • Implement strStr()
      • Reverse Words in a String
      • First Unique Character in a String
      • Count Unique Characters of All Substrings of a Given String
    • Math
      • Pow(x, n)
      • Narcissistic Number
      • A + B Problem
    • Dynamic Programming
      • Fibonacci Number
      • N-th Tribonacci Number
      • Climbing Stairs
      • Min Cost Climbing Stairs
    • LeetCode vs. LintCode Table
  • React Notes
    • Optimizing Performance in React
  • Golang Notes
    • Basics
      • Setup
      • Hello World
      • Structure
      • Data Types
      • Variables
      • Operators
      • Constants
      • Decision Making
      • Loops
      • Special Statements
    • Official Tutorial Notes
      • More Types
        • Functions
        • Pointers
        • Structs
        • Arrays
        • Slices
        • Range
        • Maps
        • More Functions
      • Methods and Interfaces
        • Methods
        • Interfaces
        • Stringers
        • Errors
        • Images
        • Readers
      • Concurrency
        • Goroutines
        • Channels
        • Range and Close
        • Select
        • Mutual Exclusion
  • Miscellaneous
    • Traveling to China During a Global Pandemic
Powered by GitBook
On this page
  • Example
  • Implicit Implementation
  • Example
  • Interface Values
  • Example
  • Nil Underlying Values
  • Nil Interface Values
  • Empty Interface
  • Example
  • Type Assertions
  • Example
  • Type Switches
  • Example

Was this helpful?

  1. Golang Notes
  2. Official Tutorial Notes
  3. Methods and Interfaces

Interfaces

This is a long section...

An interface type is a set of method signatures. A value of interface type can hold any value that implements those methods.

Example

package main

import (
    "fmt"
    "math"
)

func main() {
	var a Abser
	f := MyFloat(-math.Sqrt2)
	v := Vertex{3, 4}

	a = f  // a MyFloat implements Abser
	fmt.Println(a.Abs())
	a = &v // a *Vertex implements Abser
	fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
	if f < 0 {
		return float64(-f)
	}
	return float64(f)
}

type Vertex struct {
	X, Y float64
}
1.4142135623730951
5

Note that in line 15, if we use a = v instead, there will be an error because v is of Vertex type and does not implement Abser.

Implicit Implementation

Interfaces are implemented implicitly. A type implements an interface by implementing its methods. There is no explicit declaration of intent, no "implements" keyword. Implicit interfaces decouple the definition of an interface from its implementation, which could then appear in any package without prearrangement.

Example

package main

import "fmt"

type I interface {
    M()
}

type T struct {
    S string
}

// This method means type T implements interface I
func (t T) M() {
    fmt.Println(t.S)
}

func main() {
    var i I = T{"Oliver"}
    i.M()
}
Oliver

Interface Values

Interface values can be considered as a tuple of a value and a concrete type under the hood. An interface value holds a value of a specific underlying concrete type. Calling a method on an interface value executes the method of the same name on its underlying type.

Example

package main

import (
	"fmt"
	"math"
)

type I interface {
	M()
}

type T struct {
	S string
}

func (t *T) M() {
	fmt.Println(t.S)
}

type F float64

func (f F) M() {
	fmt.Println(f)
}

func main() {
	var i I

	i = &T{"Oliver"}
	printPair(i)
	i.M()

	i = F(math.Pi)
	printPair(i)
	i.M()
}

func printPair(i I) {
	// show value and type here
	fmt.Printf("(%v, %T)\n", i, i)
}
(&{Oliver}, *main.T)
Oliver
(3.141592653589793, main.F)
3.141592653589793

Nil Underlying Values

If the concrete value inside the interface itself is nil, the method will be called with a nil receiver.

A null pointer exception may be thrown in other languages, but in Go it is common to write methods that gracefully handle being called with a nil receiver, like the method M in the following example:

package main

import "fmt"

type I interface {
	M()
}

type T struct {
	S string
}

func (t *T) M() {
	if t == nil {
		fmt.Println("<nil>")
		return
	}
	fmt.Println(t.S)
}

func main() {
	var i I

	var t *T
	i = t
	printPair(i)
	i.M()

	i = &T{"Oliver"}
	printPair(i)
	i.M()
}

func printPair(i I) {
	fmt.Printf("(%v, %T)\n", i, i)
}
(<nil>, *main.T)
<nil>
(&{Oliver}, *main.T)
Oliver

Nil Interface Values

A nil interface value holds neither value nor concrete type.

Calling a method on a nil interface is a run-time error because there is no type inside the interface tuple to indicate which concrete method to call:

package main

import "fmt"

type I interface {
	M()
}

func main() {
	var i I
	printPair(i)
	i.M()
}

func printPair(i I) {
	fmt.Printf("(%v, %T)\n", i, i)
}
(<nil>, <nil>)
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x498fcf]

Empty Interface

The interface type that specifies zero methods is the empty interface: interface{} An empty interface may hold values of any type, i.e., every type implements at least zero methods. Empty interfaces are used by code that handles values of unknown type.

Example

package main

import "fmt"

func main() {
	var i interface{}
	printPair(i)

	i = 3.1415926
	printPair(i)
	
	i = 7
	printPair(i)

	i = "Oliver"
	printPair(i)
}

func printPair(i interface{}) {
	fmt.Printf("(%v, %T)\n", i, i)
}
(<nil>, <nil>)
(3.1415926, float64)
(7, int)
(Oliver, string)

Here, fmt.Print takes any number of arguments of type interface{}.

Type Assertions

A type assertion provides access to an interface value's underlying concrete value. t:= i.(T) means the interface value i holds the concrete type T and assigns the underlying T value to the variable t. If i does not hold a T, the statement will trigger a panic.

To test whether an interface value holds a specific type, a type assertion can return two values: the underlying value and a boolean value that reports whether the assertion succeeded.

t, ok = := i.(T)

If i holds a T, then t will be the underlying value and ok will be true.

Else, ok will be false and t will be the zero value of type T, and no panic occurs.

Example

package main

import "fmt"

func main() {
	var i interface{} = "hello"

	s := i.(string)
	fmt.Println(s)

	s, ok := i.(string)
	fmt.Println(s, ok)

	f, ok := i.(float64)
	fmt.Println(f, ok)

	f = i.(float64) // panic
	fmt.Println(f)
}
hello
hello true
0 false
panic: interface conversion: interface {} is string, not float64

Note that the the usage of the two return values s and ok is similar to its usage when reading from a map.

Type Switches

A type switch permits several type assertions in series. A type switch is similar to a regular switch statement, but the cases in a type switch specify types (not values), and those values are compared against the type of the value held by the given interface value.

The declaration in a type switch has the same syntax as a type assertion i.(T), but the specific type T is replaced with the keyword type.

Example

package main

import "fmt"

func print(i interface{}) {
    switch v := i.(type) {
        case int:
            fmt.Printf("%v is an integer\n", v)
        case string:
            fmt.Printf("%q is %v bytes long\n", v, len(v))
        default:
            fmt.Printf("I do not know about type %T\n", v)
    }
}

func main() {
	print(777)
	print("Oliver")
	print(true)
}
777 is an integer
"Oliver" is 6 bytes long
I do not know about type bool

This switch statement tests whether the interface value i holds a value of type int or string. In each case, the variable v will be of that type respectively and hold the value held by i. In the default case, the variable v is of the same interface type and value as i.

PreviousMethodsNextStringers

Last updated 4 years ago

Was this helpful?