So, channels. Converter can now convert Java classes to Go channels where possible. The previous example contains a Drop class that matches the conversion criteria, as shown in the Go example code below. Accordingly, if the converter "does not find" a class suitable for conversion, Java multithreading will be converted to Go code without using the translation into channels. *Java code:* 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 gave out:* 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) } You can run code there: Go Playground <https://go.dev/play/p/-y6f_rOa4EX> Now I'll take a break, I need to deal with the advices that I received. Thank you to all very much. среда, 18 мая 2022 г. в 13:43:07 UTC+3, alex-coder: > Henry, > thank you, it is quite possible that you are right, at least I should > check it out. > Thank you again. > > среда, 18 мая 2022 г. в 07:39:49 UTC+3, Henry: > >> Kudos to you. Java to Go is a lot of work. Java is a more complex >> language. It has more features and more possibilities for expressing the >> same model/algorithm. You need to identify all these possibilities, parse, >> and convert them to Go. I could be wrong about this, but it may be easier >> to convert Java bytecode to Go. >> >> On Tuesday, May 17, 2022 at 9:49:09 PM UTC+7 alex-coder wrote: >> >>> In Go, multithreading is one of the main features, respectively, the >>> ability to convert Java code using multithreading into Go code >>> automatically, which uses channels, is very important. >>> I found a suitable example of ProducerConsumerExample from Oracle >>> there:Oracle >>> sample >>> <https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html>, >>> >>> where the Drop class is a candidate for conversion to Go using channels. >>> But, now I give an intermediate result without channels. >>> Also, I read the opinion that the conversion of Java code where >>> annotations are used in runtime is impossible. It is necessary to >>> investigate the problem and try to understand if it is possible to solve it >>> somehow. Before transferring a project from the status of "possibility of >>> achievement" to the status of "prototype", it is necessary to see what can >>> be done with these problems in relation to annotations. >>> *Java code:* >>> 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 gave out:* >>> 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, you can run code there: >>> Go Playground. <https://go.dev/play/p/o7tXt8p2m_3> >>> >>> Thank you to all very much. >>> >>> четверг, 28 апреля 2022 г. в 19:08:51 UTC+3, alex-coder: >>> >>>> So, multithreading. >>>> I found a simple example from Oracle with the wonderful name "Bad >>>> Threads" there: >>>> >>>> https://docs.oracle.com/javase/tutorial/essential/concurrency/QandE/questions.html >>>> >>>> , simplified it even more, called the example a new simple name One and >>>> extend a Converter to translate the code to Golang. >>>> There is no similar processing for InterruptedException in go, so the >>>> Converter does not translate the processing of this interrupt in any way. >>>> If anyone has a relatively small example in Java, please share it. >>>> *Java code:* >>>> 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 >>>> } >>>> >>>> The next example will probably be about channel's. >>>> If anyone has an interesting example, write me, I'll think about how to >>>> solve it. I just can't promise that it will be quickly. :-) >>>> >>>> Thank you to all ! >>>> >>>> четверг, 7 апреля 2022 г. в 18:52:25 UTC+3, alex-coder: >>>> >>>>> Thanks for the comments about generating code to handle exceptions. . >>>>> Here it is a new version. >>>>> 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 >>>>> } >>>>> >>>>> понедельник, 4 апреля 2022 г. в 14:12:37 UTC+3, alex-coder: >>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> *Another use case for automatically translating codewritten in Java >>>>>> to Golang is Exception Handling.The next example is likely to be about >>>>>> multithreading.Example in 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 gave out:* >>>>>> >>>>>> 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") >>>>>> } >>>>>> воскресенье, 27 марта 2022 г. в 15:11:48 UTC+3, alex-coder: >>>>>> >>>>>>> After several months of switching from Java to Golang, it seemed to >>>>>>> me that >>>>>>> it would be interesting to make the translation of Java code into >>>>>>> Golang automatically. >>>>>>> The text below shows what has been done so far. >>>>>>> >>>>>>> The work is not a prototype, but rather indicates the possibility of >>>>>>> achieving a result. >>>>>>> Therefore, I deliberately simplify the development context of the >>>>>>> Converter where it was >>>>>>> possible. >>>>>>> >>>>>>> At first it seemed important to me that between Java and Go there is >>>>>>> a difference >>>>>>> between the implementation of the Dynamic Dispatching, more >>>>>>> precisely, there is no >>>>>>> Dynamic Dispatching in Go. The applied solution in the current >>>>>>> implementation >>>>>>> looks not only ugly but even violates the several very important >>>>>>> rules of the OO design, >>>>>>> I'm not kidding here. But this option looks like that it will be >>>>>>> working. >>>>>>> >>>>>>> Onward I will provide the 4 code samples in Java, followed by the >>>>>>> automatically >>>>>>> generated Golang code and comments as needed. >>>>>>> >>>>>>> *1. Of course, I started with the most popular program: "Hello >>>>>>> World".* >>>>>>> >>>>>>> package main; >>>>>>> >>>>>>> public class HelloWorld { >>>>>>> public static void main( String[] args){ >>>>>>> System.out.println("Hello World"); >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> *Converter gave out:* >>>>>>> >>>>>>> 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. Next, it was interesting to deal with the problem of a simple >>>>>>> inheritance.* >>>>>>> >>>>>>> package main; >>>>>>> >>>>>>> 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 gave out:* >>>>>>> >>>>>>> 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. In the following example, it is necessary to correctly define >>>>>>> a common interface for the inheritance tree.* >>>>>>> >>>>>>> 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 gave out:* >>>>>>> >>>>>>> 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. Now the Dynamic Dispatching absence. The problematic method in >>>>>>> the last sample is the amount() in class Repeater. Without >>>>>>> rewriting >>>>>>> the code, I think it would be impossible to invoke it correctly.* >>>>>>> >>>>>>> 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 gave out:* >>>>>>> >>>>>>> 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. I will be thankful for any feedback. Thanks to everyone.* >>>>>>> >>>>>> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a1ed3ca9-e45f-4b80-a5e2-a1eb88906362n%40googlegroups.com.