tcga癌症亚型获取_亚型多态性应用于元组的危险

tcga癌症亚型获取

这篇文章最初发表在jooq.org上 ,这是一个博客,从jOOQ的角度着眼于所有开源,Java和软件开发

Java 8有lambda和stream, 但是没有tuples ,这很可惜。 这就是为什么我们在jOOλ中实现了元组-Java 8的缺失部分 。 元组确实是无聊的值类型容器。 本质上,它们只是这些类型的枚举:

public class Tuple2<T1, T2> {
    public final T1 v1;
    public final T2 v2;
 
    public Tuple2(T1 v1, T2 v2) {
        this.v1 = v1;
        this.v2 = v2;
    }
 
    // [...]
}
 
 
public class Tuple3<T1, T2, T3> {
    public final T1 v1;
    public final T2 v2;
    public final T3 v3;
 
    public Tuple3(T1 v1, T2 v2, T3 v3) {
        this.v1 = v1;
        this.v2 = v2;
        this.v3 = v3;
    }
 
    // [...]
}

编写元组类是一项非常无聊的任务,最好使用源代码生成器来完成。

其他语言和API的元组

jOOλ的当前版本具有0至16度的元组。C#和其他.NET语言的元组类型介于1至8之间。有一个专门针对元组的特殊库,称为Javatuple ,元组在1至10之间。英里,并给元组单独的英文名称:

Unit<A> // (1 element)
Pair<A,B> // (2 elements)
Triplet<A,B,C> // (3 elements)
Quartet<A,B,C,D> // (4 elements)
Quintet<A,B,C,D,E> // (5 elements)
Sextet<A,B,C,D,E,F> // (6 elements)
Septet<A,B,C,D,E,F,G> // (7 elements)
Octet<A,B,C,D,E,F,G,H> // (8 elements)
Ennead<A,B,C,D,E,F,G,H,I> // (9 elements)
Decade<A,B,C,D,E,F,G,H,I,J> // (10 elements)

为什么?

因为当我看到Ennead时,它确实会响起那甜美的钟声。

最后但并非最不重要的一点是,jOOQ还具有一个类似于元组的内置类型org.jooq.Record ,它是Record7<T1, T2, T3, T4, T5, T6, T7>等漂亮子类型的基本类型Record7<T1, T2, T3, T4, T5, T6, T7> 。 jOOQ遵循Scala并定义了最高22级的记录。

定义元组类型层次结构时要当心

正如我们在前面的示例中看到的, Tuple3Tuple2有很多共同的代码。

由于数十年来面向对象和多态设计反模式对我们所有人都造成了严重的大脑损害,我们可能认为让Tuple3<T1, T2, T3>扩展Tuple2<T1, T2>是一个好主意,因为Tuple3只是在Tuple2的右边添加了一个属性,对吗? 所以…

public class Tuple3<T1, T2, T3> extends Tuple2<T1, T2> {
    public final T3 v3;
 
    public Tuple3(T1 v1, T2 v2, T3 v3) {
        super(v1, v2);
        this.v3 = v3;
    }
 
    // [...]
}

事实是:由于种种原因,这是您可能做的最坏的事情。 首先,是的。 Tuple2Tuple3都是元组,因此它们确实具有一些共同的特征。 将这些功能归为一个普通的超级类型并不是一个坏主意,例如:

public class Tuple2<T1, T2> implements Tuple {
    // [...]
}

但是学位不是其中之一。 这就是为什么。

排列

考虑一下您可以形成的所有可能的元组。 如果让元组彼此延伸,那么例如, Tuple5也将与Tuple2分配兼容。 以下将完美地编译:

Tuple2<String, Integer> t2 = tuple("A", 1, 2, 3, "B");

当让Tuple3扩展Tuple2 ,从扩展链中的元组中删除最右边的属性似乎是一个不错的默认选择。

但是在上面的示例中,为什么我不想重新分配(v2, v4)以使结果为(1, 3)或也许是(v1, v3) ,以使得结果为("A", 2)

当将较高程度的元组“减少”到较低程度的元组时,可能会涉及很多可能的属性。 对于所有用例,默认的最右边的属性删除方法都不会足够普遍。

类型系统

如果Tuple3扩展了Tuple2 ,则对类型系统的影响将比上述情况差得多。 例如,签出jOOQ API。 在jOOQ中,您可以放心地假设以下内容

// Compiles:
TABLE1.COL1.in(select(TABLE2.COL1).from(TABLE2))
 
// Must not compile:
TABLE1.COL1.in(select(TABLE2.COL1, TABLE2.COL2).from(TABLE2))

第一个IN谓词是正确的。 谓词的左侧只有一列( 而不是行值表达式 )。 这意味着谓词的右侧也必须对单列表达式进行操作,例如,选择单个列(相同类型)的SELECT子查询。

第二个示例选择了太多列,并且jOOQ API会告诉Java编译器这是错误的。

jOOQ通过Field.in(Select)方法保证了这一点,该方法的签名为:

public interface Field<T> {
    ...
    Condition in(Select<? extends Record1<T>> select);
    ...
}

因此,您可以提供SELECT语句,该语句产生Record1<T>类型的Record1<T>类型。

幸运的是, Record2没有扩展Record1

如果现在Record2扩展了Record1 ,那么Record1似乎是个好主意,那么第二个查询将突然编译:

// This would now compile
TABLE1.COL1.in(select(TABLE2.COL1, TABLE2.COL2).from(TABLE2))

…即使它形成无效SQL语句。 它将进行编译,因为它将生成Select<Record2<Type1, Type2>>类型,该类型将是Field.in(Select)方法中预期的Select<Record1<Type1>>的子类型。

结论

Tuple2Tuple5类型基本上是不兼容的类型。 在强类型系统中,您一定不要引诱类似类型或相关类型也应该是兼容类型。

类型层次结构是非常面向对象的,从面向对象的角度来看,我的意思是自90年代以来我们仍然遭受着有缺陷和过度设计的面向对象的概念。 即使在“企业”中,大多数人也学会了偏重于继承而不是继承 。 对于元组,组合意味着您可以很好地 Tuple5转换为Tuple2 。 但是您不能分配它。

jOOλ中 ,可以很容易地完成以下转换:

// Produces (1, 3)
Tuple2<String, Integer> t2_4 = 
    tuple("A", 1, 2, 3, "B")
    .map((v1, v2, v3, v4, v5) -> tuple(v2, v4));
 
// Produces ("A", 2)
Tuple2<String, Integer> t1_3 = 
    tuple("A", 1, 2, 3, "B")
    .map((v1, v2, v3, v4, v5) -> tuple(v1, v3));

这个想法是您对不可变值进行操作,并且可以轻松提取这些值的一部分并将其映射/重组为新值。

阅读更多

如果您喜欢阅读本文,则可能还想了解为什么递归泛型是一个糟糕的主意(在许多情况下)

翻译自: https://jaxenter.com/danger-subtype-polymorphism-applied-tuples-121755.html

tcga癌症亚型获取

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值