0

Swift(objcから来て)に慣れるだけの簡単なことをしています - guardステートメントとswitchステートメントを使用してリンクリストに目的のノードを返したい。私は明らかにelse節が巨大であるため(私のswitch文が保存されている)、guardのステートメントを悪用しています。おそらく、私はswitchという文も必要ないかもしれませんが、ちょっと上のほうを整理するだけです。ガードステートメントを誤って使用して、nilチェックを無効にする

次のように私の古いコードは次のとおりです。guard文で置き換えられ

func getValue (atIndex index: Int) -> T { 
    if count < index || index < 0 { 
     print ("index is outside of possible range") 
    } 
    var root = self.head 
    //  if var root = self.head { 
    if index == 0 { 
     return (self.head?.value)! 
    } 
    if index == count-1 { 
     return (self.tail?.value)! 
    } 
    else { 
     for _ in 0...index-1 { 
      root = root!.next! 
     } 
    } 
    return root!.value 
} 

(ただし、ガード体が通過落下しないことをコンパイラエラーを取得) - 私の問題は私の関数の戻りいるので、返すようにするものですタイプは<T>(任意のタイプ)です。

func getValue (atIndex index: Int) -> T { 
    guard (count < index || index < 0) else { 
     switch true { 
     case index == 0: 
      if let head = self.head { 
       return head.value 
      } 
     case index == count-1: 
      if let tail = self.tail { 
       return tail.value 
      } 
     default: 
      if var currentNode = head { 
       for _ in 0...index-1 { 
        currentNode = currentNode.next! 
       } 
       return currentNode.value 
      } 
     } 
    } 
} 

私は希望インデックスが範囲外であると言って私のguard文の外printステートメントを追加したいのですが、私はまた、タイプTの関数の最後に何かを返す必要があります。問題は、私のguardとswitch文の外で、私は何も返さないということです。

+3

私はあなたが警備員の利用状況を誤解したと思います。ガードに入れた条件は、*成功*の条件です。あなたがガードのボディに置くものは、*失敗*時に実行するコードであり、制御の転送( 'return'、' throw'など)につながなければなりません。したがって、成功コードはガードの直後に来なければなりません。また、 'true'を切り替えることは意味をなさない。確実に' index'を切り替えることは、それがあなたが比較しているのでより意味をなさないだろうか?また 'T 'は何ですか?あなたの関数は一般的ではありません、それはクラスジェネリックですか? – Hamish

+0

インデックスを切り替えようとしたところ、「Bool型の式パターンが 'Int'型の値と一致しません」というエラーメッセージが表示されました。リンクされたリストクラスは一般的です - インスタンス化するとき、私は各ノードの値をどのタイプのオブジェクトにするかを指定します。 –

+0

あなたの 'index'の値を' case0'、 'case_count-1'のようにする必要があります。 – Hamish

答えて

2

ようにあなたが何かをしたいと思いますので、guard文が、無効なケースをキャッチするために使用されます。guard文があればnoreturn機能を、現在のスコープ外のプログラムを移動したり、呼び出すことを意図している

func getValueAtIndex(index: Int) -> T { 
    guard index >= 0 && index < count else { 
     // Invalid case 
     print("Index is outside of possible range") 

     // Guard must return control or call a noreturn function. 
     // A better choice than the call to fatalError might be 
     // to change the function to allow for throwing an exception or returning nil. 
     fatalError("Index out of bounds") 
    } 

    // Valid cases 
} 
+1

この関数は(非voidの)戻り型を持つため、ここでは単純な 'return'はコンパイルされません。 –

+1

@MartinR良い点、それをfatalErrorに切り替え、メモを追加しました。 –

0

値はnilであることが分かる。ただし、guardswitch文全体が表示されています。

としてApple's Guard Documentationあたり:

guard文のelse句が必要であり、次のいずれかを使用して、ガード文の囲みスコープ外noreturn属性または転送プログラム制御でマークされた関数を呼び出す必要がありますどちらか文:

  • リターン
  • ブレーク
  • スロー

を続けるguardの良い例は、次のようになります。

var optValue : String? 

guard let optValue = optValue else {return} 
関連する問題