(Go : basic) 19. interface - 2

Posted by : at

Category : Go


package main

import "fmt"

type Dog struct {
	name   string
	weight int
}

type Cat struct {
	name   string
	weight int
}

func printValue(s interface{}) {
	fmt.Println(s)
}

func main() {
	//인터페이스 활용(빈 인터페이스)
	//함수내에서 어떠한 타입이라도 유연하게 매개변수로 받을 수 있다. (모든 타입 지정 가능)
	//빈 인터페이스 : 함수 매개변수, 리턴 값, 구조체 필드 등으로 사용

	//예제1
	dog := Dog{"poll", 10}
	cat := Cat{"bob", 5}

	//빈 인터페이스 : 어떤 값이든 허용 가능(유연성 증가)
	printValue(dog)
	printValue(cat)
	printValue(15)
	printValue("Animal")
	printValue(25.5)
	printValue([]Dog{})
}
$ {poll 10}
$ {bob 5}
$ 15
$ Animal
$ 25.5
$ []
package main

import "fmt"

func main() {
	//빈 인터페이스 타입 상세 설명
	//모든 타입을 나타내기 위해 빈 인터페이스 사용
	//동적타입으로 생각하면 쉽다(타 언어의 Object 타입)

	//예제1
	var a interface{}

	printContents(a)

	a = 7.5
	printContents(a)

	a = "Golang"
	printContents(a)

	a = true
	printContents(a)

	a = nil
	printContents(a)
}

func printContents(v interface{}) {
	fmt.Printf("Type : (%T) ", v) //원본 타입
	fmt.Println("ex1 : ", v)
}
$ Type : (<nil>) ex1 :  <nil>
$ Type : (float64) ex1 :  7.5
$ Type : (string) ex1 :  Golang
$ Type : (bool) ex1 :  true
$ Type : (<nil>) ex1 :  <nil>
//인터페이스 고급(3)
package main

import "fmt"
import "reflect"

func main() {
	//타입 변환
	//실행(런타임) 시에는 인터페이스에 할당한 변수는 실제 타입으로 변환 후 사용해야 하는 경우
	//인터페이스.(타입) 형식 -> 형 변환
	//interfaceVal.(type)

	//예제1
	var a interface{} = 15

	b := a
	c := a.(int)
	//d := a.(float64) //예외 발생

	fmt.Println("ex1 : ", a)
	fmt.Println("ex1 : ", reflect.TypeOf(a))

	fmt.Println("ex1 : ", b)
	fmt.Println("ex1 : ", reflect.TypeOf(b))

	fmt.Println("ex1 : ", c)
	fmt.Println("ex1 : ", reflect.TypeOf(c))

	fmt.Println()

	//예제2(저장된 타입 실제 타입 검사)
	if v, ok := a.(int); ok { //해당 타입 값, 타입 체크 결과
		fmt.Println("ex2 : ", v, ok)
	}
}
package main

import (
	"fmt"
)

func checkType(arg interface{}) {
	//arg.(type) 을 통해 현재 데이터형 반환
	switch arg.(type) {
	case bool:
		fmt.Println("This is a bool : ", arg)
	case int, int8, int16, int32, int64:
		fmt.Println("This is an int : ", arg)
	case float64:
		fmt.Println("This is a float64 : ", arg)
	case string:
		fmt.Println("This is a string : ", arg)
	case nil:
		fmt.Println("This is nil : ", arg)
	default:
		fmt.Println("What is  this type? : ", arg)
	}
}

func main() {
	//실제 타임 검사 switch 사용
	//빈 인터페이스는 어떠한 자료형도 전달 받을 수 있으므로, 타입 체크를 통해 형 변환 후 사용 가능

	//예제1
	checkType(true)
	checkType(1)
	checkType(22.542)
	checkType(nil)
	checkType("Hello Golang!")
}
package main

import (
	"fmt"
	"strconv"
)

type Account struct {
	number   string
	balance  float64
	interest float64
}

func structToMsg(arg interface{}) string {
	switch arg.(type) {
	case Account:
		o := arg.(Account)
		return "Account : " + o.number + " : " + strconv.FormatFloat((o.balance*o.interest+o.balance), 'f', -1, 64)
	case *Account:
		o := arg.(*Account)
		return "*Account : " + o.number + " : " + strconv.FormatFloat((o.balance*o.interest+o.balance), 'f', -1, 64)
	default:
		return "Error"
	}
}

func main() {

	//예제1
	fmt.Println(structToMsg(Account{number: "245-901", balance: 10000000, interest: 0.015}))
	fmt.Println(structToMsg(&Account{number: "245-902", balance: 12000000, interest: 0.035}))

	var user = new(Account)
	user.number = "245-903"
	user.balance = 15000000
	user.interest = 0.025

	fmt.Println(structToMsg(user))
}

About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links