2012-02-22 9 views
7

特定のタイプの関数を作成したかったのですが、私はそれを行う一つの方法を見つけましたが、varを使用しない以外の、きれいで良い方法がなければなりません。関数englishGreetingと宣言する代替方法は何ですか?上記の例では Goで関数タイプを操作する

package main 

import "fmt" 

type Greeting func(name string) string 

func (g Greeting) exclamation(name string) string { 
    return g(name) + "!" 
} 

var english = Greeting(func(name string) string { 
    return "Hello, " + name 
}) 

func main() { 
    fmt.Println(english("ANisus")) 
    fmt.Println(english.exclamation("ANisus")) 
} 

、私は english := Greeting...var english = Greeting...を交換することはできません、また私は Greeting(func ...)を削除し、ちょうど私が 感嘆メソッドにアクセスすることはできません funcはそれ以来一人で立つことができます。

+2

グローバル変数として 'english'を宣言しているので、' var'を削除することはできません。 – Mostafa

答えて

12

varに言及することは、あなたの主な問題であるならば、あなたはこのように、:==を変更することで、簡単にそれをドロップすることができます

english := Greeting(func(name string) string { 
    return ("Hello, " + name); 
}) 

しかし、あなたもGreetingにあなたの機能をキャストする必要はありません。仕様は以下の通りですfunction types

機能タイプは、同じパラメーターと結果タイプを持つすべての機能のセットを表します。

そして、これは約type identity:彼らは、パラメータと結果の型に対応する、パラメータと結果の値の数が同じで同一であり、どちらかの両方の機能が可変長かでもない場合

2つの関数型が同一であり、です。パラメータと結果の名前は一致する必要はありません。

これは、各機能に独自の機能タイプがあることを意味します。 2つの関数が同じシグネチャ(パラメータと結果の型)を持つ場合、それらは1つの関数型を共有します。 type Greeting func...を書くことによって、新しいものを定義するのではなく、特定の関数型に名前を付けるだけです。私はまた、あなたのenglish機能から、セミコロンや括弧を落とし

package main 

import "fmt" 

type Greeting func(name string) string 

func say(g Greeting, n string) { fmt.Println(g(n)) } 

func french(name string) string { return "Bonjour, " + name } 

func main() { 
     english := func(name string) string { return "Hello, " + name } 

     say(english, "ANisus") 
     say(french, "ANisus") 
} 

お知らせ:ゴーで関数型で動作するように正しい方法を示し

だから次のコードは動作しますが、と私は願っています。 Goの開発者は、そうでなければこれらの句読点を使用しません。

更新:サンプルコードを提供したので、私はこの問題をはっきりと理解することができました。

この目的のためには、コードは十分であり、それを行う方法はあまりありません。あなたが好きならば、あなただけのメソッドを呼び出す前にキャストすることができます:

english := func(name string) string { return "Hello, " + name } 
Greeting(english).exclamation("ANisus") 

しかし、私は、これは改善されているか分かりません。私はちょうどあなたがしたいことについては、コードを書くための他の方法ではないようだと言っています。

つまり、タイプを変更したくない場合です。つまり、関数型のメソッドを呼び出すという考えは少し変わっているようです。それは間違っているのではなく、少し稀です。より一般的な方法で同じ効果を達成する別の方法は、構造体の型を使用し、関数のフィールドを持つことです。このような何か:

package main 

import "fmt" 

type Greeting struct { 
    say func(name string) string 
} 

func newGreeting(f func(string) string) *Greeting { 
    return &Greeting{say: f} 
} 

func (g *Greeting) exclamation(name string) string { return g.say(name) + "!" } 

func main() { 
    english := &Greeting{say: func(name string) string { 
     return "Hello, " + name 
    }} 

    french := newGreeting(func(name string) string { 
     return "Bonjour, " + name 
    }) 

    fmt.Println(english.exclamation("ANisus")) 
    fmt.Println(french.exclamation("ANisus")) 
} 
ここ

englishfrenchは、同じものをコード化する2つの異なる方法を示しています。繰り返しますが、これはより優れた解決策ではなく、同じ効果を達成するためのより普遍的な、より柔軟な方法です。ここでの問題を分離しようとすると

+1

答えをありがとう。しかし、私の質問は、特定の型の関数を宣言する方法でした。あなたのコード例では決してそれをしません。私は私の例を更新しました。あなたが気づいたように、型にメソッドを追加すると、 'Greeting(func(name string)...)の部分を実行しない限りアクセスできません。 – ANisus

+0

同じパラメータと結果の型を持つ2つの関数が同一であるという前提から、タイトルを変更した理由についても理解しています。しかし、これは型のメソッドを扱う場合には当てはまりません。 'func english(...)'と 'Greeting(func english(...))'は異なるでしょう。一方は型メソッドにアクセスできず、他方は型メソッドにアクセスすることはできません。だから、最初のタイトルはもっと正しいと思います。 – ANisus

+0

ああ、更新していただきありがとうございます!あなたの答えは確かに私がそれをより良く理解する助けになりました。 'ServeHTTP(w http.ResponseWriter、req * http.Request)'メソッド( 'http.Handler'インターフェースを実装する)を持つ関数型である' websocket.Handler'を実行したときに試し始めました。再度、感謝します! – ANisus

3

type Greeting func(string) string 

func english(name string) string { 
    return return "Hello, " + name 
} 

func main() { 
    var g Greeting 
    g = english 
    fmt.Println(g("ANisus")) 
} 

はタイプあいさつの英語の関数を宣言するための方法です。注意挨拶は英語の定義には使用されていないので、特定のタイプの関数を宣言するという要件を満たしていない可能性があります。それ以外の場合は、特定の(つまり、別途定義された)タイプの関数を定義する方法はありません。

english := Greeting { 
    return return "Hello, " + name 
} 

と入力するといいかもしれませんが、いいえ、Goにはありません。英語の宣言はGreetingを使うことができず、関数の署名を繰り返す必要があります。代わりに、英語がタイプのグリーティングの要件は、割り当てでのみ行われます

g = english 

gは、グリーティングタイプとして宣言されています。英語が同じ種類でない場合、行はコンパイルされません。

型署名を繰り返すという問題以外にも、たとえば、メソッドの問題など、あなたの例の機能性を整理する他の方法を探しているかどうかは分かりません。それは確かに他の方法で行うことができます。もっと大きな例が、別の質問として提出されるかもしれませんが、助けになるでしょう。

+1

私はあなたが説明した 'english:= Greeting {...}'行を探していました。そのような方法はありません。しかし、私はGoの慣用方法で関数型を扱う方法をさらに理解できました。 – ANisus

関連する問題