백엔드, 기타/Golang

Golang 3. 2)인터페이스

데브힐러 2020. 8. 20. 07:47
반응형

1. 인터페이스

 

type 인터페이스명 interface {}

 

 예제) Printer 인터페이스

type MyInt int //'type 새_자료형' 형식으로 기존 자료형을 새 자료형으로 정의

func (i MyInt) Print(){
	fmt.Println(i)
}
type Rectangle struct {
	width, height int
}
func (r Rectangle) Print() {
	fmt.Println(r.width, r.height)
}
type Printer interface {
	Print()
}

func main() {
	var i MyInt = 5
	r := Rectangle{10, 20}
	var p Printer //インタフェース宣言
	p = i
	p.Print()

	p = r
	p.Print()
}

 

 

 슬라이스 형태로 인터페이스 초기화 하기

var i MyInt = 5
r:= Rectangle{10, 20}
pArray := []Printer{i, r} //슬라이스 형태로 인터페이스 초기화

//슬라이스를 순회하면서 Print 메서드 호출
for index,_ := range pArray {
	pArray[index].Print()
}
for _,value := range pArray {
	value.Print()
}

 

 

2. 덕타이핑

 

 위와같이 각 값이나 인스턴스의 실제 타입은 상관하지 않고 구현된 메서드로만 타입을 판단하는 방식을 덕 타이핑(Duck typing)이라고 한다.

type Duck struct {}

func (d Duck) quack() {
	fmt.Println("꽥 꽥")
}

func (d Duck) feathers() {
	fmt.Println("오리는 희색과 회색 털을 가지고 있습니다.")
}

type Person struct {}

func (p Person) quack() {
	fmt.Println("사람은 오리의 흉내를 냅니다. 꽥~~")
}

func (p Person) feathers() {
	fmt.Println("사람은 땅에서 깃털을 주워서 보여줍니다.")
}

type Quacker interface {
	quack()
	feathers()
}

func inTheForest(q Quacker) {
	q.quack() //Quacker 인터페이스로 quack 메서드 호출
	q.feathers() //Quacker 인터페이스로 feathers 메서드 호출
}

func main() {
	var donald Duck
	var david Person

	inTheForest(donald)
	inTheForest(david)
}

 

 

 # 타입이 특정 인터페이스를 구현하는지 검사

 interface{}(인스턴스).(인터페이스)

var donald2 Duck
if v, ok := interface{}(donald2).(Quacker); ok{
	fmt.Println(v, ok)
}

 

 

 # 빈 인터페이스

 

//빈 인터페이스를 사용하여 모든 타입을 받음
func formatString(arg interface{}) string {
	switch arg.(type) {
	case int:
		fmt.Println(arg)
		i := arg.(int)
		fmt.Println(i)
		return strconv.Itoa(i)

	case float32:
		f := arg.(float32)
		return strconv.FormatFloat(float64(f), 'f', -1, 32)

	case float64:
		f := arg.(float64)
		return strconv.FormatFloat(f, 'f', -1, 64)

	case string:
		s := arg.(string)
		return s

	default:
		return "Error"
	}
}

func main(){
	fmt.Println(formatString(1))
	fmt.Println(formatString(2.5))
	fmt.Println(formatString("hello"))
}

 

 

 # 빈 인터페이스로 구조체 받기

 

type Person struct {
	name string
	age int
}

func formatString(arg interface{}) string {
	switch arg.(type) {
	case Person:
		p := arg.(Person) //Person타입으로 값을 가져옴
		return p.name + " " + strconv.Itoa(p.age)
	case *Person:
		p := arg.(*Person) //*Person 타입으로 값을 가져옴
		return p.name + " " + strconv.Itoa(p.age)
	default:
		return "Error"
	}
}

func main() {
	fmt.Println(formatString(Person{"Heem", 34}))
	fmt.Println(formatString(&Person{"David", 24}))

	var andrew = new(Person)
	andrew.name = "Andrew"
	andrew.age = 35

	fmt.Println(formatString(andrew))
}

 

 

 

반응형