有什么区别
[A <: B]
Run Code Online (Sandbox Code Playgroud)
和
[+B]
Run Code Online (Sandbox Code Playgroud)
在斯卡拉?
我试图弄清楚这些词的确切含义,Covariance以及Contravariance在线的几篇文章和关于StackOverflow的问题,从我能理解的,它只是多态的另一个词.
我对上述陈述是否正确?或者我弄错了?
@uncheckedVariance 可以用来弥合Scala的声明站点方差注释和Java的不变泛型之间的差距.
scala> import java.util.Comparator
import java.util.Comparator
scala> trait Foo[T] extends Comparator[T]
defined trait Foo
scala> trait Foo[-T] extends Comparator[T]
<console>:5: error: contravariant type T occurs in invariant position in type [-T]java.lang.Object with java.util.Comparator[T] of trait Foo
trait Foo[-T] extends Comparator[T]
^
scala> import annotation.unchecked._
import annotation.unchecked._
scala> trait Foo[-T] extends Comparator[T @uncheckedVariance]
defined trait Foo
Run Code Online (Sandbox Code Playgroud)
这表示java.util.Comparator自然是反变体,即类型参数T出现在参数中,而不是返回类型.
这就引出了一个问题:为什么它还在Scala集合库中使用,它不是从Java接口扩展的?
trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBuilder[A, CC[A] @uncheckedVariance]
Run Code Online (Sandbox Code Playgroud)
此注释的有效用途是什么?
我的理解是在C#中为泛型指定方差发生在类型声明级别:当您创建泛型类型时,您指定类型参数的方差.另一方面,在Java中,指定了使用泛型的方差:当您创建某个泛型类型的变量时,您可以指定其类型参数的变化方式.
每种选择的优缺点是什么?
重写方法时,C++和Java支持返回类型协方差.
但是,它们都不支持参数类型的反差 - 相反,它转换为过载(Java)或隐藏(C++).
那是为什么?在我看来,允许这样做是没有害处的.我可以在Java中找到它的一个原因 - 因为它无论如何都有"选择最特定版本"的重载机制 - 但是不能想到C++的任何原因.
示例(Java):
class A {
public void f(String s) {...}
}
class B extends A {
public void f(Object o) {...} // Why doesn't this override A.f?
}
Run Code Online (Sandbox Code Playgroud) 我需要使用pca来识别具有特定数据集的最大方差的维度.我正在使用scikit-learn的pca来完成它,但是我无法从pca方法的输出中识别出具有最高方差的数据的组成部分.请记住,我不想消除这些维度,只能识别它们.
我的数据被组织为一个包含150行数据的矩阵,每行包含4个维度.我这样做:
pca = sklearn.decomposition.PCA()
pca.fit(data_matrix)
Run Code Online (Sandbox Code Playgroud)
当我打印pca.explained_variance_ratio_时,它会输出从最高到最低排序的方差比数组,但它不会告诉我它们对应的数据中的哪个维度(我已尝试更改矩阵中列的顺序,以及得到的方差比数组是相同的).
打印pca.components_给了我一个4x4矩阵(我把组件的原始数量留作 pca的参数)和一些我无法理解的含义的值...根据scikit的文档,它们应该是具有最大方差的组件(特征向量可能是?),但没有这些值所指的维度的标志.
转换数据也没有帮助,因为维度的改变方式我真的不知道它们最初是哪一个.
有什么方法可以用scikit的pca获取这些信息吗?谢谢
interface ICloneable<out T>
{
T Clone();
}
class Base : ICloneable<Base>
{
public Base Clone() { return new Base(); }
}
class Derived : Base, ICloneable<Derived>
{
new public Derived Clone() { return new Derived(); }
}
Run Code Online (Sandbox Code Playgroud)
鉴于这些类型声明,C#规范的哪一部分解释了为什么以下代码片段的最后一行打印"True"?开发人员可以依赖这种行为吗?
Derived d = new Derived();
Base b = d;
ICloneable<Base> cb = d;
Console.WriteLine(b.Clone() is Derived); // "False": Base.Clone() is called
Console.WriteLine(cb.Clone() is Derived); // "True": Derived.Clone() is called
Run Code Online (Sandbox Code Playgroud)
需要注意的是,如果T在类型参数ICloneable都没有声明out,则这两条线将打印"假".
协方差的一个性质是,cov(x,x)= var(x)
然而,在numpy我得到相同的结果.
from numpy import var, cov
x = range(10)
y = var(x)
z = cov(x, x)[0][1]
print y, z
Run Code Online (Sandbox Code Playgroud)
我在这里做错了吗?我怎样才能获得正确的结果?
假设我有一个简单的类型类,其实例将为我提供某种类型的值:
trait GiveMeJustA[X] { def apply(): X }
Run Code Online (Sandbox Code Playgroud)
我有一些例子:
case class Foo(s: String)
case class Bar(i: Int)
implicit object GiveMeJustAFoo extends GiveMeJustA[Foo] {
def apply() = Foo("foo")
}
implicit object GiveMeJustABar extends GiveMeJustA[Bar] {
def apply() = Bar(13)
}
Run Code Online (Sandbox Code Playgroud)
现在我有一个类似(但不相关)的类型类,它做同样的事情,但在其类型参数中是协变的:
trait GiveMeA[+X] { def apply(): X }
Run Code Online (Sandbox Code Playgroud)
在它的伴随对象中,我们告诉编译器如何从非协变类型类的实例创建实例:
object GiveMeA {
implicit def fromGiveMeJustA[X](implicit giveMe: GiveMeJustA[X]): GiveMeA[X] =
new GiveMeA[X] { def apply() = giveMe() }
}
Run Code Online (Sandbox Code Playgroud)
现在我希望implicitly[GiveMeA[Foo]]编译得很好,因为只有一种方法可以获得GiveMeA[Foo]我们在这里得到的部分.但它没有(至少不在2.10.4或2.11.2):
scala> implicitly[GiveMeA[Foo]]
<console>:16: this.GiveMeA.fromGiveMeJustA is not a valid …Run Code Online (Sandbox Code Playgroud) variance ×10
c# ×3
covariance ×3
scala ×3
java ×2
python ×2
algorithm ×1
annotations ×1
c#-4.0 ×1
c++ ×1
generics ×1
implicits ×1
numpy ×1
oop ×1
overriding ×1
pca ×1
polymorphism ×1
scala-2.8 ×1
scikit-learn ×1
statistics ×1
subtyping ×1
typeclass ×1
unchecked ×1