やじゅ@アプリケーション・ラボ わんくま支局

目次

Blog 利用状況

ニュース

プロフィール

MSMVP

[VB]遅れてやってきたYield その1

これは、Visual Basic Advent Calendar 2012 12/3日の記事。

VB2012(VB11)から、反復子のYieldステートメントが使えるようになりました。
yield自体は、C#2.0(Visual Studio 2005)から追加された機能でC#erからすれば特に目新しい機能ではありません。
(VBではC#にある「yield break」が無いです)
また、yield文は他言語ではPhythonやJavascript 1.7やRubyで使用できます。(※Rubyに関しては使い方が異なります)


反復子のYeildステートメントとは、どのような機能であるのかを書いていきたいと思います。
まず、下記のプログラムの構文と出力結果を見ると、一般的な手続き型言語での解釈では、どうしてそうなるのか非常に分かりにくいものとなります。

Module
Test
    Sub Main()
        For Each number As Integer In someNumbers()
            Console.Write(number & " ")
        Next
        'Output: 3,5,8
        Console.ReadLine()
    End Sub

    Private Iterator Function someNumbers() As System.Collections.IEnumerable
        Yield 3
        Yield 5
        Yield 8
    End Function
End Module

簡単に説明していくと、someNumersメソッドで3,5,8という数値リストを単純に生成しています。
イメージ的には、Dim someNumbers As New List(Of Integer)({3, 5, 8}) となるのですが、Yeildでは評価するタイミングが違うのです。

一般的な手続き型言語の解釈からすると、someNumbers() が逐次実行されたときに、内部上に動的な配列が生成された値を使用しているように思いますよね、それでは先ほどのList(Of Integer)と同じになってしまいます。
Yeildでは遅延評価といって、必要な時にはじめて評価する方法です。

といっても、上記のプログラムではさすがに分かりにくいため、もう少し分解してみましょう。
For Eachの正体は、デザインパターンでいう「イテレータ」であり、VB.NETのコンパイラによりコンパイル時に展開される。
http://www.atmarkit.co.jp/fdotnet/basics/oop07/oop07_03.html

Module Test
    Sub Main()
        Dim x As IEnumerator = someNumbers()

        x.MoveNext()
        Console.Write(x.Current) 'Output: 3
        x.MoveNext()
        Console.Write(x.Current) 'Output: 5
        x.MoveNext()
        Console.Write(x.Current'Output: 8

        Console.ReadLine()
    End Sub

    Private Iterator Function someNumbers() As System.Collections.IEnumerable
        Dim i As Integer
        i = 3
        Yield i
        i = 5
        Yield i
        i = 8
        Yield i
    End Function
End Module

以下に、手順を示しますが、実際にステップ実行して見ると分かりやすいと思います。
1. x に IEnumerator 型のインスタンスを受け取る(遅延評価のため、この段階ではリストは生成されない)
2. x.MoveNext で、someNumbers メソッドが呼び出される
3. someNumbers メソッドの、最初の Yield i によって、その時点の i の値である 3 が返される
4. Mainに戻り、返された値(x.Current)を表示する
5. x.MoveNext で、someNumbers メソッドが呼び出され、前回実行した「Yield i」の次のステートメントが実行される。
6. someNumbers メソッドで、次の Yield i によって、その時点の i の値である 5 が返される
7. Mainに戻り、返された値(x.Current)を表示する
8. x.MoveNext で、someNumbers メソッドが呼び出され、前回実行した「Yield i」の次のステートメントが実行される。
9. someNumbers メソッドで、次の Yield i によって、その時点の i の値である 8 が返される
10. Mainに戻り、返された値(x.Current)を表示する

このようにYieldステートメントを使用することで、処理を中断した後にその続きから処理を再開できることが出来ます。
これを「コルーチン」と呼びます。
現在、someNumbersメソッドのローカル変数 i に直接値をセットしていますが、i=5のところを i = i + 2、i=8のところを i = i + 3としても結果は同じになり、ローカル変数の値は保持されていることが分かるでしょう。

次回は、Yieldステートメントを使用したフィナボッチ数列を求めるプログラムを作成します。

投稿日時 : 2012年12月3日 0:20

コメントを追加

# http://perfecthealthus.com 2021/12/22 8:09 Dennistroub

Very informative blog post.Much thanks again. Keep writing.

# where to buy ivermectin pills http://stromectolabc.com/
ivermectin 9 mg 2022/02/08 10:35 Busjdhj

where to buy ivermectin pills http://stromectolabc.com/
ivermectin 9 mg

# pwLSRuUvalGac 2022/04/19 14:01 johnansaz

http://imrdsoacha.gov.co/silvitra-120mg-qrms

# buy ed pills https://erectionpills.best/
best ed drug 2022/06/28 11:20 ErectionPills

buy ed pills https://erectionpills.best/
best ed drug

# ロレックス 時計 アプリ 2022/08/03 22:27 vfvkxms@msn.com

注文から確認、発送までとても敏速でした(^^)お店の対応も丁寧で、とても信頼出来ます。
商品が写真で見るより綺麗で嬉しいビックリがありました。

# ed pills cheap https://erectiledysfunctionpills.shop/ 2022/10/14 16:46 Erectile

ed pills cheap https://erectiledysfunctionpills.shop/

# buy prednisone without prescription paypal https://prednisone20mg.icu/ 2022/10/15 7:20 Prednisone

buy prednisone without prescription paypal https://prednisone20mg.icu/

# local women dates https://datingtopreview.com/
top online meeting sites 2022/10/17 14:31 Dating

local women dates https://datingtopreview.com/
top online meeting sites

# prednisone purchase canada https://prednisone20mg.site/
prednisone 50 mg tablet cost 2022/11/15 11:13 Prednisone

prednisone purchase canada https://prednisone20mg.site/
prednisone 50 mg tablet cost

# best ed pills online https://ed-pills.site/
how to cure ed 2022/11/17 16:19 EdPills

best ed pills online https://ed-pills.site/
how to cure ed

# where can i get prednisone over the counter https://prednisonepills.site/
over the counter prednisone cream 2022/11/28 17:00 Prednisone

where can i get prednisone over the counter https://prednisonepills.site/
over the counter prednisone cream

# canadian meds without prescription https://noprescriptioncanada.com/
canada drug store 2022/12/13 13:42 CanadaPh

canadian meds without prescription https://noprescriptioncanada.com/
canada drug store

# cytotec pills buy online - https://cytotecsale.pro/# 2023/04/28 13:16 Cytotec

cytotec pills buy online - https://cytotecsale.pro/#

# prescription drug prices https://pillswithoutprescription.pro/# 2023/05/14 15:19 PillsPresc

prescription drug prices https://pillswithoutprescription.pro/#

# natural ed remedies https://edpill.pro/# - herbal ed treatment 2023/06/27 5:34 EdPills

natural ed remedies https://edpill.pro/# - herbal ed treatment

# herbal ed treatment https://edpillsotc.store/# - best drug for ed 2023/10/07 16:12 EdPills

herbal ed treatment https://edpillsotc.store/# - best drug for ed

# doxycycline monohydrate https://doxycycline.forum/ cheap doxycycline online 2023/11/25 3:59 Doxycycline

doxycycline monohydrate https://doxycycline.forum/ cheap doxycycline online

# 54 prednisone https://prednisone.bid/ prednisone 5 mg tablet cost 2023/12/27 2:38 Prednisone

54 prednisone https://prednisone.bid/ prednisone 5 mg tablet cost

タイトル  
名前  
URL
コメント