English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang 기본 강의

Golang 제어 문

Golang 함수 & 메서드

Golang 구조체

Golang 슬라이스 & 배열

Golang 문자열(String)

Golang 포인터

Golang 인터페이스

Golang 병행

Golang 예외(Error)

Golang 다른杂项

Go 언어 인터페이스(Interfaces)

Go 언어 인터페이스는 다른 언어와 다릅니다. Go 언어에서 인터페이스는自定义 타입으로, 하나나 여러개의 메서드 서명을 지정하는 데 사용되며, 인터페이스는 추상적인 것이므로 인터페이스의 인스턴스를 생성할 수 없습니다. 그러나 인터페이스 타입의 변수를 생성할 수 있으며, 이 변수에 인터페이스가 필요한 메서드를 가진 구체적인 타입 값을 할당할 수 있습니다. 다시 말해, 인터페이스는 메서드의 집합이자自定义 타입입니다.

인터페이스를 어떻게 생성하나요?

Go 언어에서 인터페이스를 생성하는语法은 다음과 같습니다:

type interface_name interface{
    //메서드 서명
}

예를 들어:

//인터페이스를 생성하다
type myinterface interface{
    // 메서드
    fun1() int
    fun2() float64
}

이곳에서, 인터페이스 이름은 type과 interface 키워드 사이에 포함되며, 메서드 서명은 괄호 사이에 포함됩니다.

인터페이스를 어떻게 구현하나요?

Go 언어에서 인터페이스를 구현하기 위해, 인터페이스에서 선언된 모든 메서드를 구현해야 합니다. go 언어 인터페이스는 은닉 구현입니다. 다른 언어와 마찬가지로, 인터페이스 구현을 위해 특정 키워드를 포함하지 않습니다. 다음 예제와 같이:

// Golang 프로그램이 어떻게
//인터페이스를 구현하다
package main
import "fmt"
//인터페이스를 생성하다
type tank interface {
    // 메서드
    Tarea() float64
    Volume() float64
}
type myvalue struct {
    radius float64
    height float64
}
//구현 방법
//통의 (Tank) 인터페이스
func (m myvalue) Tarea() float64 {
    return 2*m.radius*m.height + 2*3.14*m.radius*m.radius
}
func (m myvalue) Volume() float64 {
    return 3.14 * m.radius * m.radius * m.height
}
func main() {
    // 桶的接口访问
    var t tank
    t = myvalue{10, 14}
    fmt.Println("봉의 면적 :", t.Tarea())
    fmt.Println("봉의 용량:", t.Volume())
}

출력:

봉의 면적 : 908
봉의 용량: 4396

주의사항

  • 인터페이스의 default 값은 nil입니다.

  • 인터페이스가 메서드를 포함하지 않을 때, 이러한 인터페이스는 공백 인터페이스라고 합니다. 따라서 모든 타입은 공백 인터페이스를 구현합니다.

    문법:

    interface{}
  • 인터페이스 타입:이 인터페이스는 두 가지 타입이 있습니다. 하나는 정적이고, 다른 하나는 동적입니다. 정적 타입은 인터페이스 자체입니다. 예를 들어, 아래의 예제에서 tank입니다. 그러나 인터페이스에는 정적 값이 없기 때문에 항상 동적 값을 가리킵니다.
    인터페이스 타입 변수는 인터페이스를 구현하는 타입의 값을 포함하고 있으며, 따라서 이 타입의 값을 동적 값이라고 하며, 이 타입은 동적 타입입니다. 또한 구체 값과 구체 타입이라고도 합니다.

    //Go 프로그램 개념 설명
    //동적 값과 타입
    package main
    import "fmt"
    //인터페이스 생성
    type tank interface {
        // 메서드
        Tarea() float64
        Volume() float64
    }
    func main() {
        var t tank
        fmt.Println("tank interface值为: ", t)
        fmt.Printf("tank의 타입은: %T ", t)
    }

    출력:

    tank interface值为: <nil>
    tank의 타입은: <nil>

    위의 예제에서 tank라는 인터페이스가 있습니다. 이 예제에서fmt.Println("tank interface值为: ", t) 이 문장은 인터페이스의 동적 값을 반환하며, fmt.Printf("tank의 타입은: %T ", t) 문장은 인터페이스의 동적 타입을 반환합니다. 즉 nil입니다.因为这裡的接口不知道谁在实现它.

  • 타입 주장:Go 언어에서 타입 주장은 인터페이스 값에 적용됩니다. 다시 말해, 타입 주장은 인터페이스 값을 추출하는 과정입니다.

    문법:

    a.(T)

    여기서 a는 인터페이스 값이나 표현식이며, T는 타입 주장으로도 알려진 타입입니다. 타입 주장은 그 操作자의 동적 타입이 주어진 주장 타입과 일치하는지 확인하는 용도입니다. T가 구체 타입이면, 타입 주장은 a의 주어진 동적 타입이 T와 일치하는지 확인합니다. 여기서, 주장이 성공적으로 수행되면 타입 주장은 a의 동적 값을 반환합니다. 그렇지 않으면, 주장이 실패하면 예외가 발생합니다. T가 인터페이스 타입이면, 타입 주장은 T를 만족하는 주어진 동적 타입을 확인합니다. 여기서, 주장이 성공적으로 수행되면 동적 값을 추출하지 않습니다.

    //타입 주어진식 
    package main 
      
    import "fmt"
      
    func myfun(a interface{}) { 
      
        //a의 값을 추출합니다
        val := a.(string) 
        fmt.Println("값: ", val) 
    } 
    func main() { 
      
        var val interface { 
        } = "w3codebox"
          
        myfun(val) 
    }

    출력:

    값: w3codebox

    위의 예제에서,val := a.(string)문장을 변경합니다val := a.(int)이 경우, 프로그램은 panic 예외를 발생시킵니다. 따라서, 이 문제를 피하기 위해 다음 문법을 사용합니다:

    value, ok := a.(T)

    여기서, a의 타입이 T와 일치하면, 이 값은 a의 동적 값을 포함하며, ok는 true로 설정됩니다. 또한, a의 타입이 T와 일치하지 않으면, ok는 false로 설정되고, value는 기본값을 포함하며, 프로그램은 panic 예외를 발생시키지 않습니다. 다음 프로그램을 참고하세요:

    package main
    import "fmt"
    func myfun(a interface{}) {
        value, ok := a.(float64)
        fmt.Println(value, ok)
    }
    func main() {
        var a1 interface {
        } 98.09
        myfun(a1)
        var a2 interface {
        } = "w3codebox"
        myfun(a2)
    }

    출력:

    98.09 true
    0 false
  • 타입 판단:Go 인터페이스에서 타입 판단은 인터페이스의 구체 타입을 케이스 문장에서 제공된 여러 타입과 비교하는 데 사용됩니다. 이는 타입 선언과 유사하지만, 대문자로 타입을 지정하는 것이 아니라 값을 지정하는 차이가 있습니다. 또한, 타입과 인터페이스 타입을 비교할 수도 있습니다. 다음 예제와 같이:

    package main
    import "fmt"
    func myfun(a interface{}) {
        //타입 판단 사용
        switch a.(type) {
        case int:
            fmt.Println("타입: int, 값: ", a.(int))
        case string:
            fmt.Println("\n타입: string, 값: ", a.(string))
        case float64:
            fmt.Println("\n타입: float64값: ", a.(float64))
        default:
            fmt.Println("\n타입을 찾을 수 없음")
        }
    }

    출력:

    타입: string, 값: w3codebox
    타입: float64값:  67.9
    타입을 찾을 수 없음
  • 인터페이스 사용:함수나 메서드에서 다양한 유형의 파라미터를 전달하고자 할 때, 인터페이스를 사용할 수 있습니다. 예를 들어, Println() 함수와 같이. 또한, 여러 유형이 동일한 인터페이스를 구현할 때도 인터페이스를 사용할 수 있습니다.