go

Go 인터페이스

까오기 2024. 7. 11. 17:21

Go 인터페이스는 메서드의 집합을 정의하는 타입입니다. 인터페이스를 사용하면 여러 타입이 동일한 메서드를 구현할 수 있으며, 이를 통해 다형성을 구현할 수 있습니다. 인터페이스는 Go 언어의 강력한 기능 중 하나로, 코드의 유연성과 확장성을 높여줍니다.

인터페이스 정의

인터페이스는 interface 키워드를 사용하여 정의합니다. 인터페이스에는 메서드의 시그니처만 정의되며, 메서드의 구현은 해당 인터페이스를 구현하는 타입에서 정의합니다.

예제: 인터페이스 정의

package main

import "fmt"

// Speaker 인터페이스 정의
type Speaker interface {
    Speak() string
}

// Person 구조체 정의
type Person struct {
    Name string
}

// Person 타입에 대한 Speak 메서드 구현
func (p Person) Speak() string {
    return "Hello, my name is " + p.Name
}

// Dog 구조체 정의
type Dog struct {
    Name string
}

// Dog 타입에 대한 Speak 메서드 구현
func (d Dog) Speak() string {
    return "Woof! My name is " + d.Name
}

func main() {
    var s Speaker

    p := Person{Name: "Alice"}
    d := Dog{Name: "Buddy"}

    s = p
    fmt.Println(s.Speak()) // 출력: Hello, my name is Alice

    s = d
    fmt.Println(s.Speak()) // 출력: Woof! My name is Buddy
}

위 예제에서 Speaker 인터페이스는 Speak 메서드를 정의하고 있습니다. Person과 Dog 구조체는 각각 Speak 메서드를 구현하여 Speaker 인터페이스를 만족합니다. 따라서 Speaker 타입의 변수 s는 Person과 Dog 타입의 값을 모두 가질 수 있습니다.

빈 인터페이스

빈 인터페이스는 메서드가 하나도 없는 인터페이스입니다. 빈 인터페이스는 모든 타입을 포함할 수 있으며, interface{}로 표현합니다. 이를 통해 모든 타입의 값을 저장할 수 있는 변수를 만들 수 있습니다.

예제: 빈 인터페이스 사용

package main

import "fmt"

func describe(i interface{}) {
    fmt.Printf("Value: %v, Type: %T\n", i, i)
}

func main() {
    describe(42)
    describe("hello")
    describe(true)
}

위 예제에서 describe 함수는 빈 인터페이스 interface{}를 인자로 받아, 어떤 타입의 값이든 처리할 수 있습니다.

타입 어서션

타입 어서션(Type Assertion)은 인터페이스 변수가 구체적인 타입의 값을 가질 때, 해당 값을 추출하는 방법입니다.

예제: 타입 어서션 사용

package main

import "fmt"

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

    s, ok := i.(string)
    if ok {
        fmt.Println(s) // 출력: hello
    } else {
        fmt.Println("i is not a string")
    }
}

위 예제에서 i는 빈 인터페이스로 문자열 "hello"를 저장하고 있습니다. i.(string)을 사용하여 i가 문자열인지 확인하고, 맞다면 값을 추출합니다.

타입 스위치

타입 스위치는 여러 타입에 대해 타입 어서션을 처리할 때 사용됩니다.

예제: 타입 스위치 사용

package main

import "fmt"

func describe(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("Integer: %d\n", v)
    case string:
        fmt.Printf("String: %s\n", v)
    default:
        fmt.Printf("Unknown type\n")
    }
}

func main() {
    describe(42)
    describe("hello")
    describe(true)
}

위 예제에서 describe 함수는 타입 스위치를 사용하여 인자의 타입에 따라 다른 처리를 합니다.

인터페이스 활용 예제

다음은 인터페이스를 사용하여 다양한 타입을 처리하는 예제입니다.

package main

import "fmt"

// Shape 인터페이스 정의
type Shape interface {
    Area() float64
}

// Circle 구조체 정의
type Circle struct {
    Radius float64
}

// Circle 타입에 대한 Area 메서드 구현
func (c Circle) Area() float64 {
    return 3.14 * c.Radius * c.Radius
}

// Rectangle 구조체 정의
type Rectangle struct {
    Width, Height float64
}

// Rectangle 타입에 대한 Area 메서드 구현
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func printArea(s Shape) {
    fmt.Println("Area:", s.Area())
}

func main() {
    c := Circle{Radius: 5}
    r := Rectangle{Width: 4, Height: 3}

    printArea(c) // 출력: Area: 78.5
    printArea(r) // 출력: Area: 12
}

위 예제에서 Shape 인터페이스는 Area 메서드를 정의합니다. Circle과 Rectangle 구조체는 각각 Area 메서드를 구현하여 Shape 인터페이스를 만족합니다. printArea 함수는 Shape 인터페이스 타입의 값을 인자로 받아, 다양한 도형의 면적을 계산할 수 있습니다.

요약

  • 인터페이스 정의: 메서드의 집합을 정의하는 타입입니다.
  • 구현: 구조체나 사용자 정의 타입이 인터페이스의 모든 메서드를 구현하면 그 인터페이스를 만족합니다.
  • 빈 인터페이스: 모든 타입을 포함할 수 있는 인터페이스입니다.
  • 타입 어서션: 인터페이스 변수가 구체적인 타입의 값을 가질 때 해당 값을 추출하는 방법입니다.
  • 타입 스위치: 여러 타입에 대해 타입 어서션을 처리하는 방법입니다.

Go 인터페이스를 사용하면 코드의 유연성과 확장성을 높일 수 있으며, 다양한 타입을 처리하는 일반적인 코드를 작성할 수 있습니다.

 

GIT : https://github.com/kkaok/study-golang/tree/master/src/example/interface

 

study-golang/src/example/interface at master · kkaok/study-golang

Contribute to kkaok/study-golang development by creating an account on GitHub.

github.com

 

출처 : chatGPT