После нескольких месяцев перехода от Java на Golang, мне показалось, что интересно было бы сделать перевод кода Java на Golang автоматически. Нижеприведенный текст показывает, что удалось сделать на данный момент.
Работа это не прототип, а скорее указывает возможность достижения результата. Для чего я сознательно упрощаю контекст разработки Converter-a где это будет возможно.
Сначала мне показалось важным, что между Java и Go есть разница между реализацией Dynamic Dispatching, точнее в Go Dynamic Dispatching отсутствует. Примененное решение в текущей реализации Converter-a выглядит не только безобразно, но и нарушает несколько очень важных принципов в ОО проектировании. Тут я не шучу. Но вариант выглядит вполне работающим.
Далее я буду приводить код 4-х примеров кода на Java, за ним следует автоматически сгенерированный код на Golang и комментарии по необходимости.
Начал я конечно с самой популярной программы: "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")
}
Далее было интересно справиться с задачей простого наследования.
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 }
В следующем примере надо корректно определить общий для дерева наследования 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 }
Теперь об отсутствии 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 }
Я буду благодарен за любые комментарии.
Всем большое спасибо.