簡體   English   中英

雖然循環保證返回一個值,什么應該替換return語句?

[英]While loop guaranteed to return a value, what should replace return statement?

以下代碼應返回與排序數組中輸入數字“x”最接近的值。 while循環保證返回。 但編譯器可以理解地迫使我返回一個值。 我的問題是涉及最佳實踐。 在編譯器強制使用return語句的情況下,使用的一般約定是什么? 即拋出異常? 返回默認值? 等?

NOTE: I have selected "IllegalArgumentException" http://codereview.stackexchange.com/questions/47328/find-the-value-nearest-to-k-in-the-sorted-array. I dont have any answer to select, but Thank all for insight. I am not aware about SO protocols in such cases

/**
 * Given a sorted array returns the 'closest' element to the input 'x'.
 * 'closest' is defined as Math.min(Math.abs(x), Math.abs(y)) 
 * 
 * Expects a sorted array, and if array is not sorted then results are unpredictable.
 * 
 * @param a  The sorted array a
 * @return   The nearest element
 */
public static int getClosestK(int[] a, int x) {

    int low = 0;
    int high = a.length - 1;

    while (low <= high) {
        int mid = (low + high) / 2;

        // test lower case
        if (mid == 0) {
            if (a.length == 1) {
                return a[0];
            }

            return Math.min(Math.abs(a[0] - x), Math.abs(a[1] - x)) + x;
        }


        // test upper case
        if (mid == a.length - 1) {
            return a[a.length - 1];
        }

        // test equality
        if (a[mid] == x || a[mid + 1] == x) {
            return x;
        }


        // test perfect range.
        if (a[mid] < x  && a[mid + 1] > x) {
            return Math.min(Math.abs(a[mid] - x), Math.abs(a[mid + 1] - x)) + x;
        }

        // keep searching.
        if (a[mid] < x) {
            low = mid + 1;
        } else { 
            high = mid;
        }
    }

    //  return a[0]; ?????
}

如果您知道返回一個值但編譯器無法確定它,那么這是程序員錯誤,因此您可以允許自己::

throw new IllegalStateException();

而不是返回一個錯誤的值。

a是一個空數組時怎么樣? 然后會發生以下情況:

public static int getClosestK(int[] a, int x) {
    int low = 0;
    int high = a.length - 1; // 0 - 1 = -1

    while (low <= high) { // 0 <= -1 -> false
        // ...
    }
    // There is no return here. What should happen?
}

這就是編譯器強迫你返回的原因。

編譯器強制您返回該值,因為您可能永遠不會滿足while循環的條件,因此您不會進入while循環並返回該值。

在這種情況下,您將不會有應該返回int的方法的return語句。

在你的情況下,如果int[] a長度為0,你將不會返回任何東西,因為你不滿足while循環的條件。

在這種情況下,您需要validate the inputif input does not pass validation check, you can return an exception 在這里, IllegalArgumentException似乎適合我,但它完全取決於你想要拋出哪個異常。

throw new IllegalArgumentException("Error message");

如果您確定循環無法正常結束,則可以使用plain while( true )替換循環條件,而不更改代碼語義。

通常,如果您確定不會發生某些事情,請在此時拋出AssertionError ,並在消息中解釋“不可能的條件”。 在你的情況下它可能是這樣的

throw new AssertionError("not reachable");

AssertionError更適合標記“不可能”的條件,而IllegalStateException是系統狀態不允許執行某些其他有效操作的情況的正確異常。

你遇到的問題是你的while循環保證了返回,但是永遠不會輸入。

正如您的初始化值

int low  = 0;
int high = a.length - 1;

如果你傳遞一個空數組,你會得到

while(0 <= -1) {
 ...
}

作為@fge,建議您可以拋出有關非法狀態的例外情況。

你可以拋出一個RuntimeException,它是從Java語言規范中得到的例子這個

如果聲明方法具有返回類型,則其主體中的每個return語句(第14.17節)都必須具有表達式。 如果方法的主體可以正常完成,則會發生編譯時錯誤(第14.1節)。 換句話說,具有返回類型的方法必須僅使用提供值返回的return語句返回; 不允許“從身體的末端掉下來”。 請注意,方法可能具有聲明的返回類型,但不包含return語句。 這是一個例子:

     class DizzyDean {
        int pitch() { throw new RuntimeException("90 mph?!"); }
    }

您有兩種選擇:

  • 返回一些“虛擬”值
  • 拋出異常

我建議你使用異常(一些運行時異常 - IllegalStateException可能會很好),因為返回“error”值看起來更像是C風格的編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM