2014-10-17 49 views
15

我正在參加我的高中AP計算機科學課。如何正確使用goto語句

我決定把goto聲明放到我們的實驗室中,只是爲了玩耍,但我得到了這個錯誤。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
    Syntax error on token "goto", assert expected 
    restart cannot be resolved to a variable 
at Chapter_3.Lab03_Chapter3.Factorial.main(Factorial.java:28) 

我去#2一個goto問題,找出如何正確地做到這一點,我做了完全一樣的答案中的一個證明。我真的不明白爲什麼編譯器想要一個assert聲明(至少這是我想要的),也不知道如何使用assert。它似乎希望goto restart;的重新啓動部分是一個變量,但重新啓動只是一個將程序重新拉回到第10行的標籤,以便用戶可以輸入有效的int。如果它想重新啓動成爲一個變量,我該怎麼做?

import java.util.*; 

public class Factorial 
{ 
    public static void main(String[] args) 
    { 
     int x = 1; 
     int factValue = 1; 
     Scanner userInput = new Scanner(System.in); 
     restart: 
     System.out.println("Please enter a nonzero, nonnegative value to be factorialized."); 
     int factInput = userInput.nextInt(); 

     while(factInput<=0) 
     { 
      System.out.println("Enter a nonzero, nonnegative value to be factorialized."); 
      factInput = userInput.nextInt(); 
     } 

     if(x<1)//This is another way of doing what the above while loop does, I just wanted to have some fun. 
     { 
      System.out.println("The number you entered is not valid. Please try again."); 
      goto restart; 
     } 
     while(x<=factInput) 
     { 
      factValue*=x; 
      x++; 
     } 
     System.out.println(factInput+"! = "+factValue); 
     userInput.close(); 
    } 
} 
+0

歡迎來到Java。雖然'goto'是java中的一個關鍵字,它沒有功能並且會導致編譯錯誤(正如您在問題中所述)。 – DwB 2014-10-17 17:51:14

+8

小心:http://xkcd.com/292/ – 2014-10-17 17:54:55

+1

即使您找到了完美的用例並且完全有意義,也可以找到另一種方法來完成它。充其量,大多數與你一起工作的人會少想你。實際上並不是那麼糟糕,但你永遠不會超越這個恥辱。 – 2014-10-17 17:57:00

回答

50

前面已經指出的所有問題的答案goto

restart:被稱爲後跟冒號的標識符。

這裏有您需要照顧,如果你想的實現similar行爲的幾件事 -

outer:     should be placed exactly before the loop 
loopingConstructOne { we can have statements before the outer but not inbetween the label and the loop   
    inner: 
    loopingConstructTwo { 
     continue;  //goes to the top of loopingConstructTwo and continue 
     break;   //breaks out of loopingConstructTwo 
     continue outer; //goes to the outer label and reenters loopingConstructOne 
     break outer; //breaks out of the loopingConstructOne 
     continue inner; //this will behave similar to continue 
    } 
} 

我不知道是否我應該說similar,因爲我已經有了。

+2

這非常有幫助。我將不得不打印出這個答案,並將其放入我的活頁夾中進行學習和使用。 +1。你應得的+100,但我不能那樣做。 :) – Ungeheuer 2014-10-18 15:18:22

+4

這是一個很好的答案,+1,但是如果你曾經有過這樣的願望,那麼你就錯了,重新構造一段時間 - 而不是重新構造一些其他有名的方法。如果你使用這個構造,那麼你最好避免一個需要的重構,讓你的代碼變得混亂,並且用一種很少程序員理解的結構來混淆它。更可能的是,由於無法制作更清晰的代碼,您會被其他團隊認爲是一個糟糕的程序員。這樣做的願望應該被認爲是一種非常糟糕的代碼味道。 – 2014-11-25 17:02:39

+1

@BillK那麼,我會爭辯說,基本評論你可以清楚地做到這一點。只要團隊成員能理解這一點,對我來說就好了。也就是說,我對團隊有點缺乏經驗,可能根本不知道我在說什麼。 – 2016-09-23 13:45:20

2

goto在Java中沒有做任何事情。

9

Java keyword list指定goto關鍵字,但它被標記爲「未使用」。

這可能是爲了防止它被添加到更高版本的Java中。

如果goto不在列表中,並且稍後將其添加到語言中,那麼現有代碼將goto作爲標識符(變量名稱,方法名稱等等)將會中斷。但是因爲goto是一個關鍵字,所以這樣的代碼甚至不會在當前編譯,並且仍然有可能在以後實際執行某些操作,而不會破壞現有的代碼。

+2

好的地方。謝謝。我希望他們添加'goto'它非常方便。 – Ungeheuer 2014-10-18 15:19:44

+2

我希望他們永遠不會使用它。在使用Java語言(以及更早的C/C++)超過10年之後,我總能找到更好的方法來設計不使用「bug創建者」方式的函數/方法。只要看看[蘋果SSL實施安全漏洞](http://www.theguardian.com/technology/2014/feb/25/apples-ssl-iphone-vulnerability-how-did-it-happen-and-接下來是什麼)。好的,他們也忘了另一個最佳實踐:總是使用大括號,即使它使代碼更加冗長...... – 2015-12-17 16:01:43

+2

編程30多年。從頭開始,「goto」從一開始就可以提供給我,並且完全避免了整個時間。最初,其他程序員感到羞恥,不願意使用它。最後,我看到了足夠的'goto'用法,讓我對自己的信念和厭惡感有了一定的瞭解。但是,我已經看到了幾個(很少)使用(通過其他程序員,可憐的靈魂)使用'goto'更清潔的地方,而不是沒有它的地方。這些用途可能在以後得到解決。 – Les 2017-09-12 19:45:27

3

Java不支持goto,它被保留作爲的情況下,他們想將其添加到更高版本

+2

他們應該添加它。它使生活變得如此簡單。 – Ungeheuer 2014-10-18 15:16:47

+1

@Unngeheuer計數器直觀地認爲GOTO被認爲是有害的。 [Dijkstra的論點](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD215.html) – 2017-03-28 09:52:03

8

如果你看到了繼續,並打破他們接受一個「標籤」的關鍵詞。試驗一下。 Goto本身不起作用。在Java保留字,在語言不使用 -

public class BreakContinueWithLabel { 

    public static void main(String args[]) { 

     int[] numbers= new int[]{100,18,21,30}; 

     //Outer loop checks if number is multiple of 2 
     OUTER: //outer label 
     for(int i = 0; i<numbers.length; i++){ 
      if(i % 2 == 0){ 
       System.out.println("Odd number: " + i + 
            ", continue from OUTER label"); 
       continue OUTER; 
      } 

      INNER: 
      for(int j = 0; j<numbers.length; j++){ 
       System.out.println("Even number: " + i + 
            ", break from INNER label"); 
       break INNER; 
      } 
     }  
    } 
} 

Read more

+0

謝謝,這樣做很有意義。非常感謝你。 – Ungeheuer 2014-10-18 15:27:02

2

Java也不使用行號,這是GOTO函數的必要條件。與C/C++不同,Java沒有goto語句,但是java支持標籤。在嵌套循環語句之前,Java中唯一有用的地方就是它。我們可以使用break來指定標籤名稱以打破特定的外部循環。

0

Java世界中沒有'goto'。主要原因是開發人員意識到,goto的複雜代碼會導致代碼變得非常可悲,並且幾乎不可能增強或維護代碼。

但是,這段代碼可以修改一點,並使用繼續和休息的概念,我們可以使代碼工作。

import java.util.*; 

public class Factorial 
{ 
    public static void main(String[] args) 
    { 
     int x = 1; 
     int factValue = 1; 
     Scanner userInput = new Scanner(System.in); 
     restart: while(true){ 
     System.out.println("Please enter a nonzero, nonnegative value to be factorialized."); 
     int factInput = userInput.nextInt(); 

     while(factInput<=0) 
     { 
      System.out.println("Enter a nonzero, nonnegative value to be factorialized."); 
      factInput = userInput.nextInt(); 
     } 

     if(x<1)//This is another way of doing what the above while loop does, I just wanted to have some fun. 
     { 
      System.out.println("The number you entered is not valid. Please try again."); 
      continue restart; 
     } 
     while(x<=factInput) 
     { 
      factValue*=x; 
      x++; 
     } 
     System.out.println(factInput+"! = "+factValue); 
     userInput.close(); 
     break restart; 
} 
    } 
}