Форум программистов
 
Регистрация на форуме тут, о проблемах пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль

Купить рекламу на форуме 15-35 тыс рублей в месяц

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

           Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
           И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - https://clck.ru/fCqwP

Ответ
 
Опции темы Поиск в этой теме
Старый 31.03.2022, 12:20   #1
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию Переводим код с Java на Golang автоматичеки.

Не знаю в какои форуме правильно поместить заметку, тема затрагивает несколько смежных областей.
Поправьте если ошибся.

После нескольких месяцев перехода в разработке от Java на Golang, мне показалось, что
интересно было бы сделать перевод кода Java на Golang автоматически, написав Converter, так как синтаксис у обоих языков несколько похож.

Нижеприведенный текст показывает, что удалось сделать на данный момент.

Работа это не прототип, а скорее указывает возможность достижения результата.
Для чего я сознательно упрощаю контекст разработки Converter-a где это будет
возможно.

Сначала мне показалось важным, что между Java и Go есть разница между
реализацией Dynamic Dispatching, точнее в Go Dynamic Dispatching отсутствует.
Примененное решение в текущей реализации Converter-a выглядет не только
безобразно, но и нарушает несколько очень важных принципов в ОО
проектировании. Тут я не шучу. Но вариант выгдядет вполне работающим.

Далее я буду приводить код на Java, за ним следует автоматически
сгенерированный код на Golang и комментарии по-необходимости.

1. Начал я конечно с самой популярной программы: "Hello World".
Код:
package no.packeges;

public class HelloWorld {
  public static void main(  String[] args){
    System.out.println("Hello World");
  }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"os"
)

type HelloWorld struct{}

func main() {

	var args []string = os.Args

	var hw HelloWorld = HelloWorld{}
	hw.HelloWorld_main(args)
}

/** generated method **/
func (helloWorld *HelloWorld) HelloWorld_main(args []string) {
	fmt.Println("Hello World")
}
2. Далее было интересно справиться с задачей простого наследования.
Код:
package no.packeges;

public class TestInheritance {
  public static void main(  String[] args){
    Inheritance inh=null;
    inh=new Second();
    inh.hello();
    inh=new Third();
    inh.hello();
  }
}
public interface Inheritance {
  public void hello();
}
class Second implements Inheritance {
  public void hello(){
    System.out.println("Second");
  }
}
class Third implements Inheritance {
  public void hello(){
    System.out.println("Third");
  }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"os"
)

type TestInheritance struct{}

func main() {

	var args []string = os.Args

	var ti TestInheritance = TestInheritance{}
	ti.TestInheritance_main(args)
}

/** generated method **/
func (testInheritance *TestInheritance) TestInheritance_main(args []string) {

	var inh Inheritance
	inh = AddressSecond(Second{})
	inh.hello()
	inh = AddressThird(Third{})
	inh.hello()
}

type Inheritance interface {
	hello()
}
type Second struct{}

func (second *Second) hello() {
	fmt.Println("Second")
}

type Third struct{}

func (third *Third) hello() {
	fmt.Println("Third")
}

func AddressSecond(s Second) *Second { return &s }
func AddressThird(t Third) *Third    { return &t }
3. В следующем примере надо корректно определить общий для дерева наследования interface.
Код:
package no.packeges;

public class TestExtension {
  public static void main(  String[] args){
    TestExtension te=new TestExtension();
    te.hello();
    te=new Second();
    te.hello();
    te=new Third();
    te.hello();
    te=new Fourth();
    te.hello();
  }
  public void hello(){
    System.out.println("hello");
  }
}
class Second extends TestExtension {
  public void hello(){
    System.out.println("Second");
  }
}
class Third extends TestExtension {
  public void hello(){
    System.out.println("Third");
  }
}
class Fourth extends Third {
  public void hello(){
    System.out.println("Fourth");
  }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"os"
)

type TestExtension struct{}

func main() {

	var args []string = os.Args

	var te TestExtension = TestExtension{}
	te.TestExtension_main(args)
}
func (testExtension *TestExtension) hello() {
	fmt.Println("hello")
}

/** generated method **/
func (testExtension *TestExtension) TestExtension_main(args []string) {

	var te ITestExtension = AddressTestExtension(TestExtension{})
	te.hello()
	te = AddressSecond(Second{})
	te.hello()
	te = AddressThird(Third{})
	te.hello()
	te = AddressFourth(Fourth{})
	te.hello()
}

type Second struct {
	TestExtension
}

func (second *Second) hello() {
	fmt.Println("Second")
}

type Third struct {
	TestExtension
}

func (third *Third) hello() {
	fmt.Println("Third")
}

type Fourth struct {
	Third
}

func (fourth *Fourth) hello() {
	fmt.Println("Fourth")
}

type ITestExtension interface { /** Generated Method */

	hello()
}

func AddressSecond(s Second) *Second                      { return &s }
func AddressThird(t Third) *Third                         { return &t }
func AddressTestExtension(t TestExtension) *TestExtension { return &t }
func AddressFourth(f Fourth) *Fourth                      { return &f }
4. Теперь об отсутствии Dynamic Dispatching. Проблемным методом в
последнем примере является amount() в классе Repeater.
Без переписывания кода, я думаю, было бы невозможно вызвать его правильно.

Код:
package main;

public class Speaker {
  String message;
  public static void main(  String[] args){
    Speaker sp = new Speaker("Say hello !");
    System.out.println(sp.amount());
    sp.speak();
    Repeater rp = new Repeater("Say hello !",3);
    System.out.println(rp.amount());
    rp.speak();
  }
  public Speaker(  String message){
    this.message=message;
  }
  public void speak(){
    for (int i=0; i < amount(); i++) {
      System.out.println(this.message);
    }
  }
  public int amount(){
    return 1;
  }
}
class Repeater extends Speaker {
  int to_repeat=0;
  public Repeater(  String message,  int amount){
    super(message);
    this.to_repeat=amount;
  }
  public int amount(){
    return this.to_repeat;
  }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"os"
)

type Speaker struct {
	message string
}

func main() {

	var args []string = os.Args

	var s_dummy Speaker = NewSpeaker("")
	s_dummy.Speaker_main(args)
}
func NewSpeaker(message string) Speaker {

	var speaker Speaker = Speaker{message}
	return speaker
}
func (speaker *Speaker) speak() {
	for i := 0; i < speaker.amount(); i++ {
		fmt.Println(speaker.message)
	}
}
func (speaker *Speaker) amount() int {
	return 1
}

/** generated method **/
func (speaker *Speaker) Speaker_main(args []string) {

	var sp ISpeaker = AddressSpeaker(NewSpeaker("Say hello !"))
	fmt.Println(sp.amount())
	sp.speak()

	var rp ISpeaker = AddressRepeater(NewRepeater("Say hello !", 3))
	fmt.Println(rp.amount())
	rp.speak()
}

type Repeater struct {
	Speaker

	to_repeat int
}

func NewRepeater(message string, amount int) Repeater {

	var repeater Repeater = Repeater{NewSpeaker(message), amount}
	return repeater
}
func (repeater *Repeater) amount() int {
	return repeater.to_repeat
}
func (repeater *Repeater) speak() {
	for i := 0; i < repeater.amount(); i++ {
		fmt.Println(repeater.message)
	}
}

type ISpeaker interface { 

/** Generated Method */

	amount() int
/** Generated Method */

	speak()
}

func AddressRepeater(r Repeater) *Repeater { return &r }
func AddressSpeaker(s Speaker) *Speaker    { return &s }
5. Я буду благодарен за любые комментарии.

Всем большое спасибо.
mirudom вне форума Ответить с цитированием
Старый 04.04.2022, 14:04   #2
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию

Еще один вариант использования для автоматического перевода кода,
написанного на Java на Golang: Обработка Исключений.
Следующий пример скорее всего будет про многопоточность.

Пример на Java:
Код:
package com.builder.start.here;

public class CatchException {

	public static void main(String[] args) {
		try {
			new ThrowException().runme();
		} catch (Exception e) {
			System.out.println("yes, I caught it");
		} finally {
			System.out.println("finally processing");
		}

	}

}

class ThrowException{
	public void runme() throws Exception{
		throw new Exception();
	}
}
Converter выдал:

Код:
package main

import (
	"fmt"
	"os"
)

type CatchException struct{}

func main() {

	var args []string = os.Args

	var ce CatchException = CatchException{}
	ce.CatchException_main(args)
}

/** generated method **/
func (catchException *CatchException) CatchException_main(args []string) {
	defer func() {
		if err := recover(); err != nil {
			str := err.(string)
			switch str {
			case "Exception":
				fmt.Println("yes, I caught it")
			default:
				fmt.Println("No, something is not right")
			}
		}
		fmt.Println("finally processing")
	}()

	(&ThrowException{}).runme()
}

type ThrowException struct{}

func (throwException *ThrowException) runme() {
	panic("Exception")
}
mirudom вне форума Ответить с цитированием
Старый 07.04.2022, 15:12   #3
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию

Спасибо коллеге, указавшему более правильный выходной код для Java to Go Converter-а. Привожу.
Код:
package main

import (
	"fmt"
	"os"
)

type CatchException struct{}

func main() {

	var args []string = os.Args

	var ce CatchException = CatchException{}
	ce.CatchException_main(args)
}

/** generated method **/
func (catchException *CatchException) CatchException_main(args []string) {
	defer func() {
		if err := recover(); err != nil {
			str := err.(Exception)
			switch str.msg {
			case "Exception":
				fmt.Println("yes, I caught it")
			default:
				fmt.Println("No, something is not right")
			}
		}
		fmt.Println("finally processing")
	}()

	(&ThrowException{}).runme()
}

type ThrowException struct{}

func (throwException *ThrowException) runme() {
	panic(Exception{"Exception"})
}

type Exception struct {
	msg string
}
mirudom вне форума Ответить с цитированием
Старый 07.04.2022, 18:56   #4
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию

Прошу прощения, не проверил полученное решение. :-)
Привожу код, который работает.

Код:
package main

import (
	"fmt"
	"os"
)

type CatchException struct{}

func main() {

	var args []string = os.Args

	var ce CatchException = CatchException{}
	ce.CatchException_main(args)
}

/** generated method **/
func (catchException *CatchException) CatchException_main(args []string) {
	defer func() {
		if err := recover(); err != nil {
			exc := err.(Exception)
			switch exc.msg {
			case "Exception":
				fmt.Println("yes, I caught it")
			default:
				fmt.Println("No, something is not right")
			}
		}
		fmt.Println("finally processing")
	}()

	(&ThrowException{}).runme()
}

type ThrowException struct{}

func (throwException *ThrowException) runme() {
	panic(Exception{"Exception"})
}

type Exception struct {
	msg string
}
mirudom вне форума Ответить с цитированием
Старый 28.04.2022, 18:43   #5
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию Мнгопоточность, простая.

Итак, многопоточность.
Нашел у Oracle простой пример с чудным названием BadThreads там:
https://docs.oracle.com/javase/tutor...questions.html, еще более упростил его, обозвал пример новым простым именем One и дополнил Converter, что бы перевести код на Golang.
В go нет похожей обработки для InterruptedException поэтому Converter не переводит обработку данного прерывания никак. Если у кого-либо есть относительно небольшой пример на Java - прошу поделиться.
Код на Java:

Код:
package run.me;
public class One {
  String msg;
  public static void main(  String[] args) 
                throws InterruptedException {
    One one=new One();
    one.msg="Initial message";
    System.out.println("main:before start:" + 
             one.msg + " second part of");
    new Second(one).start();
    one.msg="after go start";
    Thread.sleep(2000);
    System.out.println("main:about to end:" + one.msg);
  }
}
class Second extends Thread {
  One one;
  public Second(  One one){
    this.one=one;
  }
  public void run(){
    try {
      sleep(1000);
    } catch (    InterruptedException e) {
    }
    System.out.println("run:after sleep:" + one.msg);
    one.msg="try to change msg";
  }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"os"
	"time"
)

type One struct {
	msg *string
}

func NewOne() *One {
	var one One = One{}
	return &one
}
func main() {
	var args []string = os.Args
	var o_dummy *One = NewOne()
	o_dummy.One_main(&args)
}

/** generated method **/
func (one_one *One) One_main(args *[]string) {
	var one *One = NewOne()
	s := "Initial message"
	one.msg = &s
	fmt.Println("main:before start:" + 
             *one.msg + " second part of")
	go NewSecond(one).run()
	s_s := "after go start"
	one.msg = &s_s
	time.Sleep(2000)
	fmt.Println("main:about to end:" + *one.msg)
}

type Second struct {
	one *One
}

func NewSecond(one *One) *Second {
	var second Second = Second{one}
	return &second
}
func (second *Second) run() {
	time.Sleep(1000)
	fmt.Println("run:after sleep:" + *second.one.msg)
	s_s_s := "try to change msg"
	second.one.msg = &s_s_s
}
Cледующий пример будет наверное про channel's.
Если у кого-нибудь есть интересный пример - напишите, я подумаю как его решить. Только не могу обещать, что это будет быстро. :-)
mirudom вне форума Ответить с цитированием
Старый 17.05.2022, 14:18   #6
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию Многопоточность. Часть 2.

В Go многопоточность одна из главных возможностей, соответcтвенно умение преобразования Java кода с использованием многопоточности в код на Go автоматически, который использует channels, очень важен.
Нашел у Oracle подходящий пример ProducerConsumerExample там:
ProducerConsumerExample, где класс Drop - кандидат на преобразование в Go с использованием channels.
Но, сейчас привожу промежуточный результат без channels.
Еще, прочитал мнение, что преобразование Java кода где используются аннотации в runtime-е -невозможен. Надо исследовать проблему и попытаться понять возможно ли ее как-то решить. Прежде чем переводить проект из статуса "возможность достижения" в статус "прототип" надо посмотреть, что можно сделать с указанными проблемами применительно к аннотациям.
Код на Java:
Код:
package com.builder.start.here;

import java.util.Random;

public class RunMeDrop {
	public static void main(String[] args) {
        Drop drop = new Drop();
        (new Thread(new Producer(drop))).start();
        (new Thread(new Consumer(drop))).start();
    }
}
class Drop {
    // Message sent from producer
    // to consumer.
    private String message;
    // True if consumer should wait
    // for producer to send message,
    // false if producer should wait for
    // consumer to retrieve message.
    private boolean empty = true;

    public synchronized String take() {
        // Wait until message is
        // available.
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
        // Toggle status.
        empty = true;
        // Notify producer that
        // status has changed.
        notifyAll();
        return message;
    }

    public synchronized void put(String message) {
        // Wait until message has
        // been retrieved.
        while (!empty) {
            try { 
                wait();
            } catch (InterruptedException e) {}
        }
        // Toggle status.
        empty = false;
        // Store message.
        this.message = message;
        // Notify consumer that status
        // has changed.
        notifyAll();
    }
}
class Consumer implements Runnable {
    private Drop drop;

    public Consumer(Drop drop) {
        this.drop = drop;
    }

    public void run() {
        Random random = new Random();
        for (
           String message = drop.take(); 
           ! message.equals("DONE"); 
           message = drop.take()) {
            System.out.format(
               "MESSAGE RECEIVED: %s%n", message);
        	 try {
                Thread.sleep(random.nextInt(5000));
           } catch (InterruptedException e) {}
        }
    }
}
class Producer implements Runnable {
    private Drop drop;

    public Producer(Drop drop) {
        this.drop = drop;
    }

    public void run() {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };
        Random random = new Random();

        for (int i = 0; i < importantInfo.length; i++) {
            drop.put(importantInfo[i]);
            try {
                Thread.sleep(random.nextInt(5000));
            } catch (InterruptedException e) {}
        }
        drop.put("DONE");
    }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"math/rand"
	"os"
	"sync"
	"time"
)

type RunMe struct{}

func NewRunMe() *RunMe {
	var runMe RunMe = RunMe{}
	return &runMe
}
func main() {

	var args []string = os.Args
	var rm *RunMe = NewRunMe()
	rm.RunMe_main(&args)
}

/** generated method **/
func (runMe *RunMe) RunMe_main(args *[]string) {
	wg := &sync.WaitGroup{}
	var drop *Drop = NewDrop()
	wg.Add(1)
	go (&Thread{NewProducer(drop)}).run(wg)
	wg.Add(1)
	go (&Thread{NewConsumer(drop)}).run(wg)
	wg.Wait()
}

type Drop struct {
	/** generated field */
	cond *sync.Cond
	message *string
	empty *bool
}

func NewDrop() *Drop {

	var drop Drop = Drop{}
	drop.cond = sync.NewCond(&sync.Mutex{})
	empty := true
	drop.empty = &empty
	return &drop
}
func (drop *Drop) take() string {
	drop.cond.L.Lock()
	for *drop.empty {
		drop.cond.Wait()
	}

	*drop.empty = true
	drop.cond.L.Unlock()
	drop.cond.Broadcast()
	return *drop.message
}
func (drop *Drop) put(message *string) {
	drop.cond.L.Lock()
	for !*drop.empty {
		drop.cond.Wait()
	}

	*drop.empty = false
	drop.message = message
	drop.cond.L.Unlock()
	drop.cond.Broadcast()
}

type Consumer struct {
	drop *Drop
}

func NewConsumer(drop *Drop) *Consumer {
	var consumer Consumer = Consumer{drop}
	return &consumer
}
func (consumer *Consumer) run(wg *sync.WaitGroup) {
	defer wg.Done()

	var random *Random = NewRandom()
	for message := consumer.drop.take(); 
         message != "DONE"; 
         message = consumer.drop.take() {
		fmt.Printf("MESSAGE RECEIVED: %s\n", message)
		time.Sleep(random.nextInt(5000))
	    }
}

type Producer struct {
	drop *Drop
}

func NewProducer(drop *Drop) *Producer {
	var producer Producer = Producer{drop}
	return &producer
}
func (producer *Producer) run(wg *sync.WaitGroup) {
	defer wg.Done()

	var importantInfo [4]string = [4]string{
		"Mares eat oats",
		"Does eat oats",
		"Little lambs eat ivy",
		"A kid will eat ivy too",
	}

	var random *Random = NewRandom()
	for i := 0; i < len(importantInfo); i++ {
		producer.drop.put(&importantInfo[i])
		time.Sleep(random.nextInt(5000))
	}
	s := "DONE"
	producer.drop.put(&s)
}

type Random struct{}

func NewRandom() *Random {
	var random Random = Random{}
	return &random
}

func (r *Random) nextInt(n int) time.Duration { 
    return time.Duration(rand.Intn(n)) 
}

type Thread struct {
	Runnable
}

func (t *Thread) run(wg *sync.WaitGroup) {
	t.Runnable.run(wg)
}

type Runnable interface {
	run(wg *sync.WaitGroup)
}
The Go Playground, запустить код можно там:
The Go Playground

Всем огромное спасибо.
mirudom вне форума Ответить с цитированием
Старый 22.05.2022, 09:30   #7
mirudom
 
Регистрация: 14.03.2022
Сообщений: 9
По умолчанию Channels.

Итак, channels.
Теперь converter может преобразовывать Java классы в Go channels где это возможно. Предыдущий пример содержит класс Drop, котрый соответствует критериям преобразования, что и показывает нижеприведенный код примера на Go. Соответственно, если converter "не найдет" класс подходящий для преобразования, многопоточность на Java будет преобразована в Go код без испоьзования перевода в channels.
Код на Java:
Код:
package com.builder.start.here;

import java.util.Random;

public class RunMe {
	public static void main(String[] args) {
        Drop drop = new Drop();
        (new Thread(new Producer(drop))).start();
        (new Thread(new Consumer(drop))).start();
    }
}
class Drop {
    // Message sent from producer
    // to consumer.
    private String message;
    // True if consumer should wait
    // for producer to send message,
    // false if producer should wait for
    // consumer to retrieve message.
    private boolean empty = true;

    public synchronized String take() {
        // Wait until message is
        // available.
        while (empty) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
        // Toggle status.
        empty = true;
        // Notify producer that
        // status has changed.
        notifyAll();
        return message;
    }

    public synchronized void put(String message) {
        // Wait until message has
        // been retrieved.
        while (!empty) {
            try { 
                wait();
            } catch (InterruptedException e) {}
        }
        // Toggle status.
        empty = false;
        // Store message.
        this.message = message;
        // Notify consumer that status
        // has changed.
        notifyAll();
    }
}
class Consumer implements Runnable {
    private Drop drop;

    public Consumer(Drop drop) {
        this.drop = drop;
    }

    public void run() {
        Random random = new Random();
        for (
           String message = drop.take(); 
           ! message.equals("DONE"); 
           message = drop.take()) {
            System.out.format(
               "MESSAGE RECEIVED: %s%n", message);
        	 try {
                Thread.sleep(random.nextInt(5000));
           } catch (InterruptedException e) {}
        }
    }
}
class Producer implements Runnable {
    private Drop drop;

    public Producer(Drop drop) {
        this.drop = drop;
    }

    public void run() {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };
        Random random = new Random();

        for (int i = 0; i < importantInfo.length; i++) {
            drop.put(importantInfo[i]);
            try {
                Thread.sleep(random.nextInt(5000));
            } catch (InterruptedException e) {}
        }
        drop.put("DONE");
    }
}
Converter выдал:
Код:
package main

import (
	"fmt"
	"math/rand"
	"os"
	"sync"
	"time"
)

type RunMe struct{}

func NewRunMe() *RunMe {
	var runMe RunMe = RunMe{}
	return &runMe
}
func main() {
	var args []string = os.Args
	var rm *RunMe = NewRunMe()
	rm.RunMe_main(&args)
}
/** generated method **/
func (runMe *RunMe) RunMe_main(args *[]string) {
	wg := &sync.WaitGroup{}
	var drop chan string = make(chan string)
	wg.Add(1)
	go (&Thread{NewProducer(drop)}).run(wg)
	wg.Add(1)
	go (&Thread{NewConsumer(drop)}).run(wg)
	wg.Wait()
}
type Consumer struct {
	drop chan string
}
func NewConsumer(drop chan string) *Consumer {
	var consumer Consumer = Consumer{drop}
	return &consumer
}
func (consumer *Consumer) run(wg *sync.WaitGroup) {
	defer wg.Done()
	var random *Random = NewRandom()
	for message := <-consumer.drop; 
                     message != "DONE"; 
                     message = <-consumer.drop {
		fmt.Printf("MESSAGE RECEIVED: %s\n", message)
		time.Sleep(random.nextInt(5000))
	}
}
type Producer struct {
	drop chan string
}
func NewProducer(drop chan string) *Producer {
	var producer Producer = Producer{drop}
	return &producer
}
func (producer *Producer) run(wg *sync.WaitGroup) {
	defer wg.Done()
	var importantInfo [4]string = [4]string{
                        "Mares eat oats", 
                         "Does eat oats", 
                         "Little lambs eat ivy", 
                          "A kid will eat ivy too"}
	var random *Random = NewRandom()
	for i := 0; i < len(importantInfo); i++ {
		producer.drop <- (importantInfo[i])
		time.Sleep(random.nextInt(5000))
	}
	producer.drop <- ("DONE")
}

type Random struct{}
func NewRandom() *Random {
	var random Random = Random{}
	return &random
}
func (r *Random) nextInt(n int) time.Duration { return time.Duration(rand.Intn(n)) }
type Thread struct {
	Runnable
}
func (t *Thread) run(wg *sync.WaitGroup) {
	t.Runnable.run(wg)
}
type Runnable interface {
	run(wg *sync.WaitGroup)
}
Запустить код можно в Go Playground.
Теперь я возьму паузу, надо разобраться с советами, которые я получил.

Всем большое спасибо.
mirudom вне форума Ответить с цитированием
Ответ

           Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
           Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
HEX переводим в Single Yrok Общие вопросы Delphi 6 04.03.2009 17:00
язык Си, задача - переводим в 16-й код, старшие три бита интерпретируем как некое число n drossel Помощь студентам 5 02.03.2008 17:24