Connecting

Go 언어 구조체 / 메서드 / 인터페이스 본문

Go 언어

Go 언어 구조체 / 메서드 / 인터페이스

팬도라 2020. 7. 23. 02:04
반응형

구조체

Go의 structs는 필드들로 이루어진 타입을 갖는 컬렉션입니다. 레코드를 구성하기 위해 데이터들을 그룹핑 하는데 유용합니다. 다음 예제를 통해 구조체 선언을 확인해 보세요.

type person struct {
    name string
    age  int
}

위 person 구조체 타입은 name과 age라는 필드를 가지고 있습니다. 같은 자료형을 가지고 있다면 다음과 같이 작성할 수 도 있습니다.

type person struct {
    phone, age int
}

구조체를 선언하고 필드명을 초기화 할 수 있으며, 생략된 필드는 0을 가지게 됩니다. 기본적으로 . 을 사용해서 구조체 필드에 접근하여 사용하며, &를 사용하면 구조체 포인터를 사용할 수 있습니다. 다음 예제를 통해 구조체 연습을 진행하도록 하겠습니다.

package main

import f "fmt"

type person struct {
    name string
    age  int
}

func main() {

    f.Println("구조체")

    f.Println(person{"lucas", 27})
    f.Println(person{name: "bob"})
    f.Println(person{age: 19})

    s := person{name: "kan", age: 30}
    f.Println(s.name, s.age)

    f.Println(&s)

}
package main

import f "fmt"

type subject struct {
    operatingSystem float32
    database        float32
    network         float32
    java            float32
}

func main() {

    student := subject{operatingSystem: 50, database: 30, network: 60, java: 50}
    f.Println(average(&student))

}

func average(sub *subject) float32 {

    result := (sub.operatingSystem + sub.database + sub.network + sub.java) / 4
    return result

}

메서드

우리가 알고 있는 메서드는 입력값이 있고, 그 입력값을 받아서 무언가 한 다음 결과를 도출해 내는 수학의 함수와 비슷한 개념입니다. 이때 입력값을 매개변수라고 하고,결과값을 리턴값이며, 인자( Argument )는 어떤 함수를 호출시에 전달되는 값을 의미합니다. 하지만 Go 언어에서는 클래스가 존재하지 않기 때문에 구조체만 필드값을 가지고 메서드는 별도로 분리되서 관리합니다.

다음 예제를 통해서 메서드 개념을 확인하세요.

package main

import f "fmt"

type rect struct {  // 구조체 선언
    width, height int
}

func main() {

    f.Println("메서드")

    r := rect{width: 20, height: 5}
    f.Println("area : ", r.area())
    f.Println("perim : ", r.perim())

    rp := &r
    rp.height = 10
    rp.width = 5

    f.Println("area : ", rp.area()) // 메서드 호출
    f.Println("perim : ", rp.perim())

}

// 메서드 사용
func (r *rect) area() int { // 구조체 지정
    return r.width * r.height
}

func (r rect) perim() int {
    return 2*r.width + 2*r.height
}

구조체에 정의된 두 개의 메서드를 호출했습니다. Go는 메서드 호출에 대해 값과 포인터간의 변환을 자동으로 처리합니다. 메서드 호출시 값 복사를 피하기 위해 포인터 리시버 타입을 사용할 수도 있고 전달되는 구조체를 변경할 수 있도록 할 수도 있습니다.

인터페이스

일반적으로 JAVA에서 사용하는 인터페이스는 클래스들이 구현해야 하는 동작을 지정하는데 사용되는 추상 자료형입니다. Go 언어에서는 인터페이스 타입(type)이 구현해야 하는 메서드 원형(prototype)들을 정의합니다. 즉, 하나의 사용자 정의 타입이 인터페이스를 구현하기 위해서는 단순히 그 인터페이스가 갖는 모든 메서드들을 구현하면 됩니다.

아래는 간단한 인터페이스를 생성하는 예제입니다.

package main

import f "fmt"

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

func main() {

    var i test // 인터페이스 선언
    f.Println(i)

}

현재는 아무것도 없는 인터페이스를 생성하고 호출했기 때문에 nil 값이 호출됩니다. 인터페이스를 사용할 때는 변수를 선언하는 방식과 동일하며, 다른 자료형과 동일하게 함수의 매개변수, 리턴값, 구조체의 필드로 사용할 수 있습니다.

다음 예제를 통해 구조체와 메서드, 인터페이스를 확인해 보세요.

package main

import (
    f "fmt"
    "math"
)

type geometry interface {
    area() float64
    perim() float64
}

type rect struct {
    width, height float64
}

type circle struct {
    radius float64
}

func main() {

    f.Println("인터페이스")

    r := rect{width: 3, height: 4}
    c := circle{radius: 5}
    measure(r)
    measure(c)

}

func (r rect) area() float64 {
    return r.width * r.height
}

func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}

func measure(g geometry) {
    f.Println(g)
    f.Println(g.area())
    f.Println(g.perim())
}
Comments