2009-09-28 33 views
4

有沒有辦法來翻譯機械陳述gotoifswitchwhilebreakcontinue報表等,或函數調用,對象,什麼?翻譯goto語句來如果交換機,同時,破發等

+1

到底爲什麼你需要知道這一點?這只是一個思想實驗,或者你有什麼真正的理由? – Kip 2009-09-28 13:59:24

+1

模擬一個goto應該是不必要的 - 在極少數情況下,使用goto不是一個糟糕設計的症狀。 – 2009-09-28 14:02:31

回答

9

雖然這不是一個好主意,但可以使用循環和開關。在下面的例子中,goto變量決定什麼標籤(0,1,2或默認值)在轉爲繼續時轉到。

int goTo=0; 
while(true){ 
    switch(goTo){ 
    case 0: 
    doSomething(); 
    goTo = 1; 
    continue; 
    case 1: 
    doSomethingElse(); 
    goTo = 2; 
    continue; 
    case 2: 
    doSOmethingDifferent(); 
    goTo = 0; 
    continue; 
    default: 
    return; 
    } 
} 
+2

實際上沒有什麼內在的關於該代碼塊的壞主意(雖然我不知道是否將它用作解決沒有goto的方法)這只是一個有限狀態機的基本實現,它有很多合法目的。 – Falaina 2009-09-28 14:06:13

+0

Java中的while循環不能具有整數條件。 'while(true)' – pjp 2009-09-28 14:07:01

+1

謝謝pjp。能夠將1作爲true和0傳遞爲false是我真正希望他們添加到Java中的一件事。其餘的是美好的。 – Marius 2009-09-28 14:19:07

3

考慮到這goto的可以創建基於其地方之間的跳躍,這是非常值得懷疑的複雜性。

+0

我把原來的問題表示爲:「我有一個應用程序使用goto遍佈整個地方,我想創建一個應用程序來完成代碼,並用if來替換goto,for循環,函數等等擺脫他們。「當我試圖回答這個問題時,其他人似乎試圖回答「我怎樣才能做出一個模擬使用goto的開關?」我認爲這些用處不大。 – 2009-09-28 15:05:02

+0

+1我明白你的意思 – Kip 2009-09-28 15:15:03

+0

+1你以同樣的方式閱讀問題,我或多或少同意你的答案。可能會自動檢測和替換GOTO的特定用途 - 但在一般情況下這樣做可能不可行。 – slim 2009-09-28 15:29:39

4

Java語言不支持將goto模擬到任意位置所需的功能(即使在相同的方法中也不行)。您可以使用您提到的構造實現goto的一些簡單用途,但不能實現所有可能的goto這種方式。 (*)

在字節代碼級別上,您可能實現goto(至少在方法中),但是在這種情況下,該字節代碼無法映射回有效的Java代碼。

至於goto s表示交叉法或對象邊界:這絕對是一個很大的禁忌在JVM上水平。整個Java安全模型取決於代碼可驗證的事實,因此只有定義的入口點(也稱爲「方法」)。 (*)免責聲明:這裏假定您不想完全重構方法來實現goto的效果,也可能會調用代碼重複和混淆方法的「正常」流。既然你可以在Java方法實現圖靈機你絕對可以實現「轉到」在Java方法;-)

0

是,使用你所提到的方法的組合......這是可能的(一切皆有可能真的,只是想清楚如何正確地做到這一點是屁股疼痛)。

請記住,goto可能會導致極其複雜的執行路徑...因此可能會導致在生成的任何內容中出現難看的大量重複代碼。

+0

它不需要*重複,必要時只需要大量的樣板。見下文。 – 2009-09-28 14:38:52

0

在實踐中,我想任何給定的例子goto可以被翻譯成別的東西,特別是如果方法提取是允許的轉型。這是一個抽象的問題,還是你真的有這麼多的goto,你真的需要一個實際的工具?也許java代碼本身是從某種機器翻譯過來的?

我習慣把一個實際goto到每一個項目我寫只是爲了激怒較真。

6

我認爲這將是值得在這裏分享。有一天,我在Reddit上看到了這一點,它是通過自定義類加載器轉到任意行號(在相同的.java文件中)的實現。這是一段有趣的代碼。 http://steike.com/tmp/goto.zip。我對此不以爲然。

編輯: 對於那些誰是好奇,但不想下載zip並運行它,以下文件:

public class GotoDemo { 

    public static void main(String[] args) { 
     int i = 5; 
     System.out.println(i); 
     i = i - 1; 
     if (i >= 0) { 
      GotoFactory.getSharedInstance().getGoto().go(4); 
     } 

     try { 
      System.out.print("Hell"); 
      if (Math.random() < 2) throw new Exception();    
      System.out.println("World!"); 
     } catch (Exception e) { 
      System.out.print("o "); 
      GotoFactory.getSharedInstance().getGoto().go(13);    
     } 
    } 
} 

它會打印:

3 
    2 
    1 
    0 
    Hello World! 
+7

這很有趣......一個可怕的方式。 – 2009-09-28 14:14:13

+1

我的大腦在哭泣 – Kip 2009-09-28 15:15:46

+0

@JoachimSauer最可怕的部分是單身。 – rightfold 2014-11-25 08:22:46

2

當然:(爲了清晰起見稍微縮寫)

int goTo = 0; boolean done = false; 
while (!done) { 
    switch (goTo) { 
    default: 
    case 1: System.out.println("We're at line 1!"); goTo = 2; break; 
    case 2: System.out.println("We're going to line 4!"); goTo = 4; break; 
    case 3: System.out.println("We're at line 3 and we're done!"); done = true; break; 
    case 4: System.out.println("We're at 4, going to 2! Screw you, line 3!"); goTo = 2; break; 
    } 
} 

爲什麼你會想要做這樣的事我是無法理解,但是,嘿,你可以 ...

+1

這與Marius的回答幾乎完全一致。正如那裏指出的那樣,這是一個有限狀態機(即將「goTo」更改爲「狀態」)。FSM沒什麼問題,但將它用作goto解決方法會很奇怪。 – Kip 2009-09-28 14:47:33

+0

是的,他在我編輯窗口時發佈了......多線程的危險...... 這很奇怪。但它回答了OP的要求。 – 2009-09-28 17:16:08