3

ジェネリックスを使用して関数を定義しましたが、コンパイラが表示するエラーを理解するのに苦労しています。問題は次のように簡単に表現できます。

def myfunc[T <: MyClass](param:MyClass):T = param

それは私の体にこのエラーを与えますparam: MyClass 型の式は、期待される型 T に準拠していません。

なんで?paramT の上限に適合します。param を T にキャストすることに頼らずに、このようなものをどのように機能させることができますか?

4

5 に答える 5

8

Ok。以下があるとします。

class Animal
class Dog extends Animal

そして今、あなたの機能を以下に持ってみましょう:

def myfunc[T <: Animal](param:Animal):T = param

とりあえず、コンパイラはエラーをスローしないと仮定します。を呼び出すと、関数定義に従ってmyfunc[Dog](new Animal)a を返す必要があります。Dogしかし実際には、あなたはただ送り返しているだけAnimalです。これは許可されるべきではありません。したがって、エラー。

今だったら:

def myfunc[T >: Dog](param:Dog):T = param

ここで呼び出しmyfunc[Animal](new Dog)ます。戻り値の型は ですAnimal。しかし、この関数は、 であるのと同じように正しい aをDog返します。それが明確になることを願っていますDogAnimal

于 2012-12-13T05:36:25.200 に答える
4

後方分散があります。の場合T <: MyClass、予想されるT場所を指定できますMyClassMyClassただし、期待される場所を指定することはできませんT

説明する:

def myfunc(x: Any): String = x

これにより、同じ理由で同じエラーが発生します。はAnyではなく、StringあなたMyClassは ではありませんT

これはあなたが意味したかもしれないことです:

def myfunc[T >: MyClass](param:MyClass):T = param

これはうまくいきます。

于 2012-12-13T01:23:32.953 に答える
1

共通の祖先を共有しているため、paramがTに関連しているというあなたの仮定は間違っています。

たとえば、基本クラスAは、2 つのサブクラスBおよびCを持つことができます。TB型で、paramがC型の場合、paramはTに関連する型ではありません。

于 2012-12-13T19:05:25.923 に答える
1

これを見てください:

class A(); class B extends A;

scala> def myfunc[T <: A,U >: A](param: U):T = param
<console>:8: error: type mismatch;
found   : param.type (with underlying type U)
required: T
       def myfunc[T <: A,U >: A](param: U):T = param

Javaのように、param:MyClass実際には下限 ( >: MyClass) があります。 の任意の子孫にすることができますMyClassmyfunc(B)では、クラス ダイアグラムでより高い型を実行して返すにはどうすればよいAでしょうか。継承図で B が A よりも低いと見なされた場合、B を返しますが、実際には<: A. エラー。

T、U、V などのすべての型を明示的に宣言し、コンパイラが何を言っているかを確認すると便利な場合があります。

于 2012-12-13T01:22:39.650 に答える
0

お役に立てれば幸いです。

引数の型は MyClass ではなく T です。

object StackOverFlow13851352 extends App {
    class MyClass
    class YourClass extends MyClass
    def myfunc[T <: MyClass](param: T): T = param

    val clazz: YourClass = myfunc(new YourClass)
}

Scala コード ランナー バージョン 2.10.0-RC2 -- Copyright 2002-2012、LAMP/EPFL

Java バージョン「1.7.0_09」

于 2012-12-13T01:12:48.360 に答える