2016-05-18 11 views
0

インタフェースに問題があります。インタフェース機能GoLangでの呼び出し

ここは私のmain.goファイルです。

package main 

import (
    "fmt" 
    "bitbucket.org/xyz/trash/a" 
) 

// Second - 
type Second interface { 
    Area() float64 
} 

// Area - 
func Area() float64 { 
    return 2 
} 


func main() { 

    r := new(a.Rect) 

    n := new(Second) 

    r.F = *n 

    fmt.Println(r.Area()) 

} 

他のパッケージ、a.go;

package a 

// First - 
type First interface { 
    Area() float64 
} 

// Rect - 
type Rect struct { 
    F First 
} 

// Area - 
func (r Rect) Area() float64 { 
    return 1 
} 

私はない "1"、 "2" を印刷する

fmt.Println(r.Area())

この行を期待しています。私は何が欠けていますか?

ありがとうございました。

答えて

1

まず、コードをもう一度見てください。書かれているように、a.Rect.Area()は1を返します。常に1を返します。好きなすべてのプロパティを設定します。 1を返します。あなたの歯を噛んで、神々を呪う。それは1を返します。それは1を返す関数なので、それは何をしているのです。

はこのようにそれを書く:

// Area - 
func (r Rect) Area() float64 { 
    return r.F.Area() 
} 

...とあなたは別の問題を持っているので、あなたはパニックます。

Area()のmain.goには受信機がありません。それはインターフェイスとは関係ありません。それは単なる関数です。オブジェクトはありません。何も実装していません。多型はありません。いいえ、別に。

あなたはnをインターフェイスへのポインタとして宣言しましたが、インターフェイスの実装ではありません。それはゼロです。逆参照しようとすると、全世界が空に落ちるでしょう。

n.Area()に電話をしたい場合は、Secondを具体的なタイプにしてください。 (main.goで)

// Second - 
type Second struct {} 

// Area - 
func (s Second) Area() float64 { 
    return 2 
} 

あなたは違いを参照していますか?今すぐのは、Area()メソッドの受信者であるため、というインターフェイスを実装しています。したがって、期待される動作を得ることができます。

+0

今はっきりしています。ありがとう。 – Quaso

2

どのインタフェースが誤解されていますか? goでは、型はインタフェース用に定義された関数を実装する場合、インタフェースを実装します。したがって、あなたのコードでは、a.Firstmain.Secondのインターフェイスは相当のです。型は、その両方を実装するか、まったく実装しません。

したがって、タイプRectは、a.Firstmain.Secondの両方です。 Rectの中のフィールドFは、First(またはFirst)が同じであるために実装される別の型を含むことを意味します。

r.Area()に電話すると、func (r Rect) Area() uint64という関数が実行されます。回線r.F = *nを使用して、インターフェイスをSecond to Firstに割り当てます(これは同等ですが問題ありません)。しかし、r.F.Area()を呼び出そうとすると、FがFirstを実装する型ではないのでパニックになります。です。

したがって、Firstを実装する別の型を作成し、それをrに代入する必要があります。その後r.F.Area()に電話することができます。

+0

ねえ。ありがとう。実際に私が達成しようとしているのは、 "r"に私の新しいインターフェース(n)を持たせることです。グローバル関数を呼び出さない。 – Quaso

+0

すでにRectのインターフェイスを実装していますが、変更することはできません。私は私の答えを少し精緻化した。 –

関連する問題