본문 바로가기
카테고리 없음

Go언어의 구조체(메서드, 임베딩, 인터페이스, Panic) 2장

by 조이럭키7 2023. 3. 31.
반응형

구조체 2장을 보기전에 1장 구조체 포인터와 Struct를 숙지하지 않았다면 아래 포스팅을 이용하여 숙지하고 2장을 참고하자

https://joylucky7.tistory.com/29

 

Go언어의 구조체(포인터, Struct) 1장

◆ 포인터 ▶ 메모리 참조를 저장하는 자료형 var 변수명 *자료형 ● nil(null)로 초기화 package main import "fmt" func main() { var numPtr *int fmt.Println(numPtr) } ▶ new(자료형)으로 메모리를 할당 package main import

joylucky7.tistory.com


◆ 메서드

▶ 타입에 연결하는 함수

func (리시버이름 * 구조체타입 또는 구조체타입) 함수이름(매개변수)리턴타입{}
package main

import "fmt"

type Rectangle struct {
  width  int
  height int
}

func (rect *Rectangle) getWidth() int {
  return rect.width
}

func (rect *Rectangle) getHeight() int {
  return rect.height
}

func main() {
  rect := Rectangle{20, 10}
  fmt.Println(rect.getWidth())
}

구조체 타입을 설정하면 참조가 대입되고 구조체 타입을 설정하면 복제가 됨

package main

import "fmt"

type Rectangle struct {
  width  int
  height int
}

func (rect *Rectangle) setWidth(width int) {
  rect.width = width
}

func (rect Rectangle) setHeight(height int) {
  rect.height = height
}

func main() {
  rect := Rectangle{20, 10}
  rect.setWidth(50)
  fmt.Println(rect)
  rect.setHeight(50)
  fmt.Println(rect)
}

리시버가 사용이 안 될때는 _

package main

import "fmt"

type Rectangle struct {
  width  int
  height int
}

func (_ *Rectangle) display() {
  fmt.Println("Rectangle")
}

func main() {
  rect := Rectangle{20, 10}
  rect.display()
}

구조체 안에 다른 구조체를 생성 -has a

package main

import "fmt"

type Person struct {
  name string
  age  int
}

func (p *Person) greeting() {
  fmt.Println("Hello~")
}

type Student struct {
  p      Person
  school string
  grade  int
}

func main() {
  var s Student
  s.p.greeting()
}

구조체 안에 다른 구조체 타입만 선언 -is a

package main

import "fmt"

type Person struct {
  name string
  age  int
}

func (p *Person) greeting() {
  fmt.Println("Hello~")
}

type Student struct {
  Person
  school string
  grade  int
}

func main() {
  var s Student
  s.greeting()
}

메서드 오버라이딩

package main

import "fmt"

type Person struct {
  name string
  age  int
}

func (p *Person) greeting() {
  fmt.Println("Super")
}

type Student struct {
  Person
  school string
  grade  int
}

func (s *Student) greeting() {
  fmt.Println("Sub")
}

func main() {
  var s Student
  s.Person.greeting()
  s.greeting()
}

◆ Interface

메서드의 선언만 존재하는 개체

type 인터페이스이름 interface{}

package main

import "fmt"

type Service interface { // 인터페이스 정의
}

func main() {
  var service Service    // 인터페이스 선언
  fmt.Println(service) // <nil>: 빈 인터페이스이므로 nil이 출력됨
}

인터페이스 사용_1

package main

import "fmt"

type MyInterface interface{
  GetName() string
  GetAge() int
}

type Person struct{
  name string
  age int
}

func (p Person) GetName()string{
  return p.name
}

func (p Person) GetAge()int{
  return p.age
}

func main() {
  var myInterfaceValue MyInterface

  var p = Person{}
  p.name = "Jack"
  p.age = 39

  // 인터페이스 사용
  myInterfaceValue = p
  fmt.Println(myInterfaceValue.GetName())
  fmt.Println(myInterfaceValue.GetAge())
}

 인터페이스 사용_2

package main

import "fmt"

type MyInterface interface{
  GetName() string
  GetAge() int
}

type Person struct{
  name string
  age int
}

func (p Person) GetName()string{
  return p.name
}

func (p Person) GetAge()int{
  return p.age
}

func main() {
  p := Person{"Alice", 26}
  printNameAndAge(p)
}

func printNameAndAge(i MyInterface){
  fmt.Println(i.GetName(),i.GetAge())
}

 인터페이스 사용_3

package main

import "fmt"

type MyInterface interface{
  GetName() string
  GetAge() int
}

type Person struct{
  name string
  age int
}

func (p Person) GetName()string{
  return p.name
}

func (p Person) GetAge()int{
  return p.age
}

type PersonWithTitle struct{
  name string
  title string
  age int
}

func (p PersonWithTitle) GetName()string{
  // <칭호> <빈칸> <이름> 반환
  return p.title + " " + p.name
}

func (p PersonWithTitle) GetAge() int{
  return p.age
}

func main() {
  p := PersonWithTitle{"Alice", "Dr", 26}
  printNameAndAge(p)
}

func printNameAndAge(i MyInterface){
  fmt.Println(i.GetName(),i.GetAge())
}

 인터페이스 사용_4

package main

import "fmt"

type Starcraft interface{
  Attack()
}

type Protoss struct{
  name string
}

func (p Protoss) Attack(){
  fmt.Println(p.name, " 공격")
}

type Zerg struct{
  name string
}

func (z Zerg) Attack(){
  fmt.Println(z.name, " 공격")
}

type Terran struct{
  name string
}

func (t Terran) Attack(){
  fmt.Println(t.name, " 공격")
}

func main() {
  var star Starcraft
  star = Protoss{"질럿"}
  star.Attack()

  star = Zerg{"히드라"}
  star.Attack()

  star = Terran{"마린"}
  star.Attack()
}

◆ Panic

Go 언어는 panic이라는 특수한 내장 함수를 제공

panic 함수를 호출하면 프로 그램을 중단하고 패닉 메시지를 반환

panic을 제때 처리하지 않으면 프로그램 이 종료되므로 신중하게 사용해야 함

package main

import "fmt"

func main() {
  panicTest(true)
  fmt.Println("Hello Panic")
}

func panicTest(p bool) {
  if p {
  panic("panic requested")
  }
}

프로그램이 중단되지 않도록 할려면 defer recover() 이용

recover()panic이 발생하지 않으면 nil을 반환하고 발생하면 패닉 메시지를 리턴

package main

import "fmt"

func main() {
  panicTest(true)
  fmt.Println("Hello Panic")
}

func checkPanic() {
  if r := recover(); r != nil {
  fmt.Println("A Panic was captured, message:", r)
  }
}
func panicTest(p bool) { // defer와 recover 조합
  defer checkPanic()
  if p {
  panic("panic requested")
  }
}

 

반응형

댓글