Réaliser un générateur PHP / Python avec Golang / Ruby

Réaliser un générateur avec Golang (Go) / Ruby

[Ici](http://qiita.com/hiroykam/items/2fea445fd2d489354c34#%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AC%E3%83%BC%E3 Lorsque j'étudiais des générateurs en PHP et Python3 avec% 82% BF), j'ai étudié comment cela pouvait être réalisé dans Golang et Ruby.

Générateur avec PHP, Python3, Golang, Ruby2.4

J'ai lu "numbers.txt" et j'ai préparé un générateur simple qui produit les résultats de sortie suivants.

numbers.txt


zero
one
two
three
four
five

Résultat de sortie


0:zero
1:one
2:two
3:three
4:four
5:five

Pour PHP

Vérifié avec PHP 5.6. Je n'ai pas sélectionné PHP7 car je n'ai pas utilisé yield from cette fois.

<?php

function my_generator($name)
{
    $file = fopen($name, "r");

    if ($file) {
        while ($line = fgets($file)) {
            yield $line;
        }
    }
    fclose($file);
}

$g = my_generator("numbers.txt");
foreach ($g as $k => $v) {
    print($k. ":". $v);
}

Pour Python

Cela peut être réalisé de la même manière que PHP. J'ai utilisé la version 3.5 comme version Python.

def my_generator(name):
    with open(name) as lines:
        for line in lines:
           yield line

g = my_generator("numbers.txt")
for k, v in enumerate(g):
    print("%s:%s" % (k, v), end="")

Pour Golang

Golang n'a pas l'équivalent de PHP ou Python yield (voir Reference ici). Par conséquent, nous avons réalisé quelque chose de similaire en utilisant le canal ou la fermeture Goroutine.

Méthode utilisant le canal Goroutine

En supposant que le nombre de lignes dans numbers.txt sera énorme, il y a des problèmes de performances.

package main

import (
    "bufio"
    "fmt"
    "os"
)

func yield(fp *os.File) chan string {
    ch := make(chan string)

    go func() {
        defer close(ch)

        scanner := bufio.NewScanner(fp)
        for scanner.Scan() {
            ch <- scanner.Text()
        }
        if err := scanner.Err(); err != nil {
            panic(err)
        }
    } ()

    return ch
}

func main() {
    fp, err := os.Open("numbers.txt")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    i := 0
    for s := range(yield(fp)) {
        fmt.Printf("%d:%s\n", i, s)
        i++
    }
}

Méthode utilisant la fermeture

Il peut y avoir un moyen de synchroniser avec sync.Mutex.

package main

import (
    "bufio"
    "fmt"
    "os"
)

func yield(fp *os.File) func() (bool, string) {
    scanner := bufio.NewScanner(fp)
    return func() (bool, string) {
        t := scanner.Scan()
        if err := scanner.Err(); err != nil {
            panic(err)
        }
        return t, scanner.Text()
    }
}

func main() {
    fp, err := os.Open("numbers.txt")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    y := yield(fp)
    for i := 0;;i++ {
        t, s := y()
        if !t { break }
        fmt.Printf("%d:%s\n", i, s)
    }
}

Pour Ruby 2.4

Ruby a aussi yield, mais c'est une définition de fonction qui reçoit des blocs au lieu d'un générateur comme PHP / Python. Il y a ʻEnumerator` comme fonction équivalente au générateur PHP / Python, et il est décrit comme suit.

def my_generator(name)
  return to_enum(__method__, name) unless block_given?
  IO.foreach(name) do |line|
    yield(line.chomp)
  end
end

g = my_generator('numbers.txt')
g.with_index { |l, i| p '%d:%s' % [i, l] }

Ici, s'il y a un bloc, le bloc est traité, et s'il n'y a pas de bloc, il peut être traité comme une méthode qui renvoie Enumerator.

Recommended Posts

Réaliser un générateur PHP / Python avec Golang / Ruby
Proxy dynamique avec python, ruby, PHP
Combinaisons qui se chevauchent avec des limites supérieures en Python / Ruby / PHP / Golang (Go)
J'ai essayé d'utiliser mecab avec python2.7, ruby2.3, php7
Combinaison de regroupement en Python / Ruby / PHP / Golang (Go)
Java VS PHP VS Python VS Ruby
Zundokokiyoshi avec python / rubis / Lua
À propos de Perl, Python, PHP, Ruby
Gérer les nombres premiers avec Python / Ruby / PHP / Golang (Go)
Hiérarchie, ordre, combinaison (dupliquée) en Python / Ruby / PHP / Golang (Go)
Scraping avec Node, Ruby et Python
générateur de nombres aléatoires français avec python
Réaliser un pool de connexion DB avec Golang
Gestion des expressions régulières par PHP / Python
Envoyer l'image avec python et enregistrer avec php
Exemple PHP / Python / Ruby frappant l'API Path
[Grammaire de base] Différences entre Ruby / Python / PHP
Essayez d'appeler Python depuis Ruby avec une économie
Crypter avec Ruby (Rails) et décrypter avec Python
Scraping Web facile avec Python et Ruby
J'ai essayé de frapper l'API Mastodon avec Ruby (Faraday) / Python (Pycurl) / PHP (Curl)
FizzBuzz en Python3
Grattage avec Python
Comment profiter de la programmation avec Minecraft (Ruby, Python)
Statistiques avec python
Grattage avec Python
Python avec Go
Twilio avec Python
Intégrer avec Python
[Python] Fonction de générateur
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
avec syntaxe (Python)
Bingo avec python
Zundokokiyoshi avec python
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
De l'état initial de CentOS8 à l'exécution de php python perl ruby avec nginx
Tendances 2014 du cadre d'application Web (PHP / Java / Ruby / Python / Perl)
Notez qu'écrire comme ça avec ruby c'est écrire comme ça avec python
Une histoire d'essayer un monorepo (Golang +) Python avec Bazel
Premiers pas avec Google App Engine pour Python et PHP
python, php, ruby Comment convertir un décimal en n
Écrivons respectivement Python, Ruby, PHP, Java, JavaScript
Comparaison de CoffeeScript avec la grammaire JavaScript, Python et Ruby
Gestion des versions de Node, Ruby et Python avec anyenv
Comment gérer JSON en Ruby, Python, JavaScript, PHP
Communication série avec Python
Zip, décompressez avec python
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Communication de socket avec Python
Analyse de données avec python 2
Grattage en Python (préparation)
Essayez de gratter avec Python.
Tutoriel [Docker] (Python + php)
Recherche séquentielle avec Python