2016-12-19 9 views
0

オブジェクトの型がAnyであることがわかっていたときに、関数の引数のコンパイルタイプを関数のシグネチャに定義されている期待された型に強制的に設定する方法はありますか?私はそれを簡単な例で説明しましょう。コンパイル時の関数の引数がScalaの特定の型になるようにするには?

def writeInt(value: Int): Unit { ... } 

def writeString(value: String): Unit { ... } 

def get(name: String): Any = { ... } 

は、私は次のコードを作ることができる方法を明示的getリターンが使用されるべきことを述べるために彼のプログラムでwriteInt機能を参照するプログラマを強制することなく正常にコンパイル:

たちは、次の3つの機能を定義していることを考えると.asInstanceOf[Int]getので

writeInt(get("dividend").asInstanceOf[Int]) // this works... 
writeInt(get("dividend"))     // but this does not :(

Intならびにであってもよい、Anyオブジェクトを返すことができますは、スカイラで醜い.asInstanceOf[Int]表記でそれを解決するためのエレガントな方法はありますか?私はget("dividend")ことを知って、

writeString(get("name").asInstanceOf[String]) // this works... 
writeString(get("name"))      // but this does not :(

基本的に:

プログラムの他の部分では、私はそれぞれ再び.asInstanceOf[String]を入力することなく、同じ機能を使用してこのコードを書くことができるようにしたいと思いますのでご注意くださいIntを返し、get("name")Stringを返します。しかし、どのように私はあまりにも混乱せずにコンパイラにそれを知らせることができますか?

+4

私は短い答えは「いいえ」だと思います。戻り値の型がAnyの場合、コンパイラが知る方法はありません。 – marios

+0

一つのアイデアは、あなたのゲッターに 'def get [Name]:String ... def get [Id]:Long'という文字列ではなく、その型で動作させることです。名前とIDはここで作成したカスタムタイプです。 – marios

+0

面白いアイデアをありがとうございますが、私のユースケースではうまくいかないでしょう。文字列は、外部から来る任意の文字列になるため、型に置き換えることはできません。文字通り何でもかまいません。 –

答えて

2

writeメソッドのラッパーを使用することもできます。

def writeAny(a: Any): Unit = a match { 
    case s: String => writeString(s) 
    case i: Int => writeInt(i) 
} 

より良い解決策は、あなたのget()メソッドの戻り値Either[String,Int]を持っているでしょう。次に、あなたのコードはこのような何か行うことができます:一般的なルールとして

get(str).fold(writeString, writeInt) 

を、Anyは可能な限り避けるべきです。

+0

これらの「書き込み」メソッドはここでは例として示しています。あなたがそれらを呼び出すとき、彼らは "私"ではないので、私は本当にそれらを変更することはできません。推論の中で考えることができるビルトインまたはカスタムの方法で置き換えることができます。"def substring(int beginIndex)"または "def startsWith(String prefix)"が役立ちます。私のコントロールの中にあるのは、 "def get(name:String)"メソッドの定義だけです。私は戻り値の型をキャストしないようにする何らかの方法をパラメータ化する方法が存在するかどうか疑問に思っていますが、何らかの形で "name"引数から推測します。私は "配当"は常に "Int"であることを知っています。 –

関連する問題