Go 인터페이스
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
출처 : chatGPT