日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

本文介紹了為什么比較返回一個(gè)整數(shù)的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

我最近在SO聊天中看到了一次討論,但沒有明確的結(jié)論,所以我最終在那里詢問了一下。

這是出于歷史原因還是與其他語言的一致性?當(dāng)查看各種語言的compareTo的簽名時(shí),它返回一個(gè)int

為什么它不返回枚舉。例如,在C#中我們可以這樣做:

enum CompareResult {LessThan, Equals, GreaterThan};

和:

public CompareResult CompareTo(Employee other) {
    if (this.Salary < other.Salary) {
         return CompareResult.LessThan;
    }
    if (this.Salary == other.Salary){
        return CompareResult.Equals;
    }
    return CompareResult.GreaterThan;
}

在Java中,枚舉是在這個(gè)概念之后引入的(我不記得C#了),但它可以通過一個(gè)額外的類來解決,比如:

public final class CompareResult {
    public static final CompareResult LESS_THAN = new Compare();
    public static final CompareResult EQUALS = new Compare();
    public static final CompareResult GREATER_THAN = new Compare();

    private CompareResult() {}
}  

interface Comparable<T> {
    Compare compareTo(T obj);
}

我之所以這樣問,是因?yàn)槲艺J(rèn)為int不能很好地表示數(shù)據(jù)的語義。

例如在C#中

l.Sort(delegate(int x, int y)
        {
            return Math.Min(x, y);
        });

及其在Java 8中的孿生兄弟

l.sort(Integer::min);

編譯兩者是因?yàn)?code>Min/min尊重比較器接口的約定(接受兩個(gè)int并返回一個(gè)int)。

顯然,這兩種情況的結(jié)果都不是預(yù)期的。如果返回類型為Compare,則會(huì)導(dǎo)致編譯錯(cuò)誤,從而迫使您實(shí)現(xiàn)”正確”行為(或者至少您知道自己在做什么)。

此返回類型丟失了很多語義(并且可能會(huì)導(dǎo)致難以找到的錯(cuò)誤),那么為什么要這樣設(shè)計(jì)它?

推薦答案

[此答案適用于C#,但在某種程度上可能也適用于JAVA。]

這是出于歷史、性能和可讀性的原因。它可能會(huì)在兩個(gè)方面提高性能:

    實(shí)現(xiàn)比較的位置。通常,您只需返回”(lhs-rhs)”(如果值是數(shù)值類型)。但這可能很危險(xiǎn):請參見下面的內(nèi)容!
    調(diào)用代碼可以使用<=>=來自然地表示對應(yīng)的比較。與使用枚舉相比,這將使用單個(gè)IL(因此使用處理器)指令(盡管有一種方法可以避免枚舉的開銷,如下所述)。

例如,我們可以按如下方式檢查lhs值是否小于或等于rhs值:

if (lhs.CompareTo(rhs) <= 0)
    ...

使用枚舉,如下所示:

if (lhs.CompareTo(rhs) == CompareResult.LessThan ||
    lhs.CompareTo(rhs) == CompareResult.Equals)
    ...

這顯然可讀性較差,而且效率也很低,因?yàn)樗M(jìn)行兩次比較。您可以通過使用臨時(shí)結(jié)果來修復(fù)低效:

var compareResult = lhs.CompareTo(rhs);

if (compareResult == CompareResult.LessThan || compareResult == CompareResult.Equals)
    ...

它的可讀性仍然很差,而且它的效率也更低,因?yàn)樗鼒?zhí)行兩個(gè)比較操作而不是一個(gè)(盡管我坦率地承認(rèn),這樣的性能差異很可能不會(huì)有什么問題)。

正如raznagul在下面指出的,你實(shí)際上可以通過一個(gè)比較來做到這一點(diǎn):

if (lhs.CompareTo(rhs) != CompareResult.GreaterThan)
    ...

所以您可以使其相當(dāng)高效–但當(dāng)然,可讀性仍然會(huì)受到影響。... != GreaterThan不如... <=清楚

(當(dāng)然,如果使用枚舉,則無法避免將比較結(jié)果轉(zhuǎn)換為枚舉值的開銷。)

因此,這樣做主要是出于可讀性的原因,但在某種程度上也是出于效率的原因。

最后,正如其他人所提到的,這也是出于歷史原因。像C的strcmp()memcmp()這樣的函數(shù)總是返回整數(shù)。

匯編比較指令也傾向于以類似的方式使用。

例如,要在x86匯編程序中比較兩個(gè)整數(shù),可以這樣做:

CMP AX, BX ; 
JLE lessThanOrEqual ; jump to lessThanOrEqual if AX <= BX

CMP AX, BX
JG greaterThan ; jump to greaterThan if AX > BX

CMP AX, BX
JE equal      ; jump to equal if AX == BX

您可以看到與CompareTo()的返回值的明顯比較。

附錄:

這里有一個(gè)例子,它表明使用從LHS中減去RHS的技巧來獲得比較結(jié)果并不總是安全的:

int lhs = int.MaxValue - 10;
int rhs = int.MinValue + 10;

// Since lhs > rhs, we expect (lhs-rhs) to be +ve, but:

Console.WriteLine(lhs - rhs); // Prints -21: WRONG!

顯然,這是因?yàn)樗阈g(shù)溢出。如果您為生成打開了checked,則上面的代碼實(shí)際上會(huì)引發(fā)異常。

因此,最好避免使用減法進(jìn)行比較的優(yōu)化。(參見下面Eric Lippert的評(píng)論。)

這篇關(guān)于為什么比較返回一個(gè)整數(shù)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標(biāo)簽:整數(shù) 返回
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評(píng)定2018-06-03

通用課目體育訓(xùn)練成績評(píng)定