日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

亚型多态性应用于元组的危险

發布時間:2023/12/3 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 亚型多态性应用于元组的危险 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 8具有lambda和stream,但是沒有元組,這真是令人遺憾 。 這就是為什么我們在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)

為什么?

因為當我看到恩納德時,它真的會敲響那甜蜜的鐘聲

最后但并非最不重要的一點是,jOOQ還具有一個類似于元組的內置類型org.jooq.Record ,它是Record7<T1, T2, T3, T4, T5, T6, T7>等漂亮子類型的基本類型Record7<T1, T2, T3, T4, T5, T6, T7> 。 jOOQ遵循Scala并定義了最高22級的記錄。

定義元組類型層次結構時要當心

正如我們在前面的示例中看到的, Tuple3與Tuple2有很多共同的代碼。

由于數十年來的對象定向和多態設計反模式對我們所有人都造成了嚴重的大腦損害,我們可能認為讓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;}// [...] }

事實是:由于種種原因,這是您最糟糕的事情。 首先,是的。 Tuple2和Tuple3都是元組,因此它們確實具有一些共同的特征。 將這些功能歸為一個普通的超級類型并不是一個壞主意,例如:

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 ,則對類型系統的影響將遠遠大于上述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);... }

因此,您可以提供一個產生Record1<T>類型的任何子類型的SELECT語句。

幸運的是, 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>>的子類型。

結論

Tuple2和Tuple5類型基本上是不兼容的類型。 在強類型系統中,您一定不要引誘類似類型或相關類型也應該是兼容類型。

類型層次結構是非常面向對象的,從面向對象的角度來看,我的意思是自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://www.javacodegeeks.com/2015/10/the-danger-of-subtype-polymorphism-applied-to-tuples.html

總結

以上是生活随笔為你收集整理的亚型多态性应用于元组的危险的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。