转载:GitHub - jiyinyiyong/swift-is-like-go: Comparing Swift syntax with Go’s
# BASICS
# Hello World
# Swift
# Go
1 2 3 4 5 6 7 package mainimport "fmt" func main () { fmt.Println("Hello, world!" ) }
# C#
1 Console.WriteLine("Hello, world!" );
# SCALA
1 println("Hello, world!" )
# Variables And Constants
# Swift
1 2 3 4 5 var myVariable = 42 myVariable = 50 let myConstant = 42 let explicitDouble: Double = 70
# GO
1 2 3 4 5 var myVariable = 42 myVariable = 50 const myConstant = 42 const explicitDouble float64 = 70
# C#
1 2 3 4 5 var myVariable = 42 ;myVariable = 50 ; const int myConstant = 42 ;double explicitDouble = 70 d;
# SCALA
1 2 3 4 5 var myVariable = 42 myVariable = 50 val myConstant = 42 val explicitDouble: Double = 70
# Type Coercion
# Swift
1 2 3 let label = "The width is " let width = 94 let widthLabel = label + String (width)
# Go
1 2 3 const label = "The width is " const width = 94 var widthLabel = label + strconv.Itoa(width)
# C#
1 2 3 var label = "The width is " ;var width = 94 ;var widthLabel = label + width;
# SCALA
1 2 3 val label = "The width is " val width = 94 val widthLabel = label + width
# String Interpolation
# Swift
1 2 3 4 let apples = 3 let oranges = 5 let fruitSummary = "I have \(apples + oranges) " + "pieces of fruit."
# GO
1 2 3 const apples = 3 const oranges = 5 fruitSummary := fmt.Sprintf("I have %d pieces of fruit." , apples + oranges)
# C#
1 2 3 4 var apples = 3 ;var oranges = 5 ;var fruitSummary = $"I have {apples + oranges} " + "pieces of fruit." ;
# SCALA
1 2 3 4 val apples = 3 val oranges = 5 val fruitSummary = s"I have ${apples + oranges} " + " pieces of fruit."
# Range Operator
# Swift
1 2 3 4 5 6 7 8 9 let names = ["Anna" , "Alex" , "Brian" , "Jack" ]let count = names.countfor i in 0 ..< count { print ("Person \(i + 1 ) is called \(names[i]) " ) }
# GO
1 2 3 4 5 6 7 8 names := [4 ]string {"Anna" , "Alex" , "Brian" , "Jack" } for i, value := range (names) { fmt.Printf("Person %v is called %v\n" , (i + 1 ), value) }
# C#
1 2 3 4 5 6 7 8 9 var names = new []{"Anna" , "Alex" , "Brian" , "Jack" };var count = names.Count();for (var i; i< count; i++) { Console.WriteLine($"Person {i + 1 } is called {names[i]} " ); }
# SCALA
1 2 3 4 5 6 7 8 9 val names = Array ("Anna" , "Alex" , "Brian" , "Jack" )val count = names.lengthfor (i <- 0 until count) { println(s"Person ${i + 1} is called ${names(i)} " ) }
# Inclusive Range Operator
# Swift
1 2 3 4 5 6 7 8 for index in 1 ... 5 { print ("\(index) times 5 is \(index * 5 ) " ) }
# GO
1 2 3 4 5 6 7 8 for i := 1 ; i <= 5 ; i++ { fmt.Printf("%d times 5 is %d" , i, i*5 ) }
# C#
1 2 3 4 5 6 7 8 foreach (var index in Enumerable.Range(1 ,5 )) { Console.WriteLine($"{index} times 5 is {index * 5 } " ); }
# SCALA
1 2 3 4 5 6 7 8 for (index <- 1 to 5 ) { println(s"$index times 5 is ${index * 5} " ) }
# COLLECTIONS
# Arrays
# Swift
1 2 var shoppingList = ["catfish" , "water" , "tulips" , "blue paint" ]shoppingList[1 ] = "bottle of water"
# GO
1 2 var shoppingList = []string {"catfish" , "water" , "tulips" , "blue paint" }shoppingList[1 ] = "bottle of water"
# C#
1 2 val shoppingList = new [] { "catfish" , "water" , "tulips" , "blue paint" }; shoppingList[1 ] = "bottle of water" ;
# SCALA
1 2 var shoppingList = Array ("catfish" , "water" , "tulips" , "blue paint" )shoppingList(1 ) = "bottle of water"
# Maps
# Swift
1 2 3 4 5 var occupations = [ "Malcolm" : "Captain" , "Kaylee" : "Mechanic" , ] occupations["Jayne" ] = "Public Relations"
# GO
1 2 3 4 5 var occupations = map [string ]string { "Malcolm" : "Captain" , "Kaylee" : "Mechanic" , } occupations["Jayne" ] = "Public Relations"
# C#
1 2 3 4 5 var occupations = new Dictionary { { "Malcolm" , "Captain" }, { "Kaylee" , "Mechanic" } }; occupations["Jayne" ] = "Public Relations" ;
# SCALA
1 2 3 4 5 var occupations = scala.collection.mutable.Map ( "Malcolm" -> "Captain" , "Kaylee" -> "Mechanic" ) occupations("Jayne" ) = "Public Relations"
# Empty Collections
# Swift
1 2 3 4 let emptyArray = [String ]()let emptyArray:[String ] = []let emptyDictionary = [String : Float ]()let emptyDictionary[String : Float ] = [:]
# Go
1 2 3 4 5 var ( emptyArray []string emptyDictionary = make (map [interface {}]interface {}) emptyArrayNoType []interface {} )
# C#
1 2 var emptyArray = new string [0 ];var emptyMap = new Dictionary<String, float >();
# SCALA
1 2 3 val emptyArray = Array [String ]()val emptyDictionary = Map [String , Float ]()val emptyArrayNoType = Array ()
# FUNCTIONS
# Functions
# Swift
1 2 3 4 func greet (name : String , day : String ) -> String { return "Hello \(name) , today is \(day) ." } greet("Bob" , "Tuesday" )
# Go
1 2 3 4 5 6 7 func greet (name, day string ) string { return fmt.Sprintf("Hello %v, today is %v." , name, day) } func main () { greet("Bob" , "Tuesday" ) }
# C#
1 2 3 4 string greet (string name, string day ) { return $"Hello {name} , today is {day} ." ; } greet("Bob" , "Tuesday" );
# SCALA
1 2 3 4 5 6 7 8 9 10 def greet (name: String , day: String ): String = { return s"Hello $name , today is $day ." } greet("Bob" , "Tuesday" ) def greet (name: String , day: String ): String = s"Hello $name , today is $day ." greet("Bob" , "Tuesday" )
# Tuple Return
# Swift
1 2 3 func getGasPrices () -> (Double , Double , Double ) { return (3.59 , 3.69 , 3.79 ) }
# Go
1 2 3 func getGasPrices () (float64 , float64 , float64 ) { return 3.59 , 3.69 , 3.79 }
# C#
1 2 3 4 (double , double , double ) GasPrices(long id) { return (3.59 , 3.69 , 3.79 ); }
# SCALA
1 2 3 4 5 6 def getGasPrices (): (Double , Double , Double ) = { return (3.59 , 3.69 , 3.79 ) } def getGasPrices = (3.59 , 3.69 , 3.79 )
# Variable Number Of Arguments
# Swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func sumOf (_ numbers : Int ...) -> Int { var sum = 0 for number in numbers { sum += number } return sum } sumOf(42 , 597 , 12 ) func sumOf (numbers : Int ...) -> Int { var sum = 0 for number in numbers { sum += number } return sum } sumOf(numbers: 42 , 597 , 12 )
# Go
1 2 3 4 5 6 7 8 9 10 11 12 func sumOf (numbers ...int ) int { var sum = 0 for _, number := range (numbers) { sum += number } return sum } func main () { sumOf(42 , 597 , 12 ) sumOf([]int {42 , 597 , 12 }...) }
# C#
1 2 3 4 5 6 7 8 9 10 11 12 13 int sumOf (params int [] args ) { var sum = 0 ; for (number in numbers) { sum += number; } return sum; } sumOf(42 , 597 , 12 ); int sumOf (params int [] args ) => args.Sum();sumOf(42 , 597 , 12 );
# SCALA
1 2 3 4 5 6 7 8 9 10 11 def sumOf (numbers: Int *): Int = { var sum = 0 for (number <- numbers) { sum += number } return sum } sumOf(42 , 597 , 12 ) Array (42 , 597 , 12 ).sum
# Function Type
# Swift
1 2 3 4 5 6 7 8 func makeIncrementer () -> ((Int ) -> Int ) { func addOne (number : Int ) -> Int { return 1 + number } return addOne } var increment = makeIncrementer()increment(7 )
# Go
1 2 3 4 5 6 7 8 9 10 func makeIncrementer () func (int ) int { return func (number int ) int { return 1 + number } } func main () { increment := makeIncrementer() increment(7 ) }
# C#
1 2 3 4 5 Func makeIncrementer ( ) => (int number) => { return 1 + number; };var increment = makeIncrementer();increment(7 );
# SCALA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def makeIncrementer (): Int => Int = { def addOne (number: Int ): Int = { return 1 + number } return addOne } var increment = makeIncrementer()increment(7 ) def makeIncrementer : Int => Int = (number: Int ) => 1 + number var increment = makeIncrementerincrement(7 )
# Map
# Swift
1 2 3 4 var numbers = [20 , 19 , 7 , 12 ]numbers.map({ number in 3 * number }) numbers.map{number in number * 3 } numbers.map{$0 * 3 }
# Go
1 2 3 4 5 6 7 8 9 10 11 12 13 mapFunc := func (slice interface {}, fn func (a interface {}) interface {}) interface {} { val := reflect.ValueOf(slice) out := reflect.MakeSlice(reflect.TypeOf(slice), val.Len(), val.Cap()) for i := 0 ; i < val.Len(); i++ { out.Index(i).Set( reflect.ValueOf(fn(val.Index(i).Interface())), ) } return out.Interface() } a := mapFunc([]int {1 , 2 , 3 , 4 }, func (val interface {}) interface {} { return val.(int ) * 3 })
# C#
1 2 var numbers = new []{20 , 19 , 7 , 12 };numbers.Select(i => i*3 ).ToArray();
# SCALA
1 2 var numbers = Array (20 , 19 , 7 , 12 )numbers.map( number => 3 * number )
# Sort
# Swift
1 sort([1 , 5 , 3 , 12 , 2 ]) { $0 > $1 }
# Go
1 sort.Sort(sort.Reverse(sort.IntSlice([]int {1 , 5 , 3 , 12 , 2 })))
# C#
1 2 new []{1 , 5 , 3 , 12 , 2 } .OrderBy(i => i);
# SCALA
1 Array (1 , 5 , 3 , 12 , 2 ).sortWith(_ > _)
# Named Arguments
# Swift
1 2 3 4 5 func area (width : Int , height : Int ) -> Int { return width * height } area(width: 10 , height: 10 )
# Go
# C#
1 2 3 4 5 6 int Area (int width, int height ) { return width * height; };Area(width: 2 , height: 3 ); Area(2 , height: 2 ); Area(height: 3 , width: 2 );
# SCALA
1 2 3 4 5 def area (width: Int , height: Int ): Int = { return width * height } area(width = 10 , height = 10 )
# CLASSES
# Declaration
# Swift
1 2 3 4 5 6 class Shape { var numberOfSides = 0 func simpleDescription () -> String { return "A shape with \(numberOfSides) sides." } }
# Go
1 2 3 4 5 6 type Shape struct { numberOfSides int } func (p *Shape) simpleDescription () string { return fmt.Sprintf("A shape with %d sides." , p.numberOfSides) }
# C#
1 2 3 4 5 class Shape { var numberOfSides = 0 ; string SimpleDescription ( ) => $"A shape with {numberOfSides} sides." ;}
# SCALA
1 2 3 4 5 6 7 8 9 10 11 12 13 class Shape { var numberOfSides = 0 def simpleDescription (): String = { return s"A shape with $numberOfSides sides." } } class Shape (var numberOfSides: Int = 0 ) { def simpleDescription = s"A shape with $numberOfSides sides." }
# Usage
# Swift
1 2 3 var shape = Shape ()shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()
# Go
1 2 3 var shape = new (Shape)shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()
# C#
1 2 3 var shape = new Shape();shape.numberOfSides = 7 ; var shapeDescription = shape.SimpleDescription();
# SCALA
1 2 3 var shape = new Shape ()shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()
# Subclass
# Swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class NamedShape { var numberOfSides: Int = 0 var name: String init (name : String ) { self .name = name } func simpleDescription () -> String { return "A shape with \(numberOfSides) sides." } } class Square : NamedShape { var sideLength: Double init (sideLength : Double , name : String ) { self .sideLength = sideLength super .init (name: name) numberOfSides = 4 } func area () -> Double { return sideLength * sideLength } override func simpleDescription () -> String { return "A square with sides of length \(sideLength) ." } } let test = Square (sideLength: 5.2 , name: "square" )test.area() test.simpleDescription()
# Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 type NamedShape struct { numberOfSides int name string } func NewNamedShape (name string ) *NamedShape { return &NamedShape{ name: name, } } func (p *NamedShape) SimpleDescription () string { return fmt.Sprintf("A shape with %d sides." , p.numberOfSides) } type Square struct { *NamedShape sideLength float64 } func NewSquare (sideLength float64 , name string ) *Square { return &Square{ NamedShape: NewNamedShape(name), sideLength: sideLength, } } func (p *Square) Area () float64 { return p.sideLength * p.sideLength } func (p *Square) SimpleDescription () string { return fmt.Sprintf("A square with sides of length %d." , p.sideLength) } func main () { a := NewSquare(5.2 , "square" ) a.Area() a.SimpleDescription() }
# C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class NamedShape(string name) { var numberOfSides = 0 ; string SimpleDescription ( ) => $"A shape with {numberOfSides} sides." ;} class Square(decimal sideLength, string name) : NamedShape(name) { public Square ( ) { numberOfSides = 4 ; } int Area ( ) => sideLength*sideLength; override string SimpleDescription ( ) => "A square with sides of length $sideLength." ; } val test = new Square(5.2 , "square" ); test.Area(); test.SimpleDescription();
# SCALA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class NamedShape (var name: String , var numberOfSides: Int = 0 ) { def simpleDescription = s"A shape with $numberOfSides sides." } class Square (var sideLength: Double , name: String ) extends NamedShape (name, numberOfSides = 4 ) { def area = sideLength * sideLength override def simpleDescription = s"A square with sides of length $sideLength ." } val test = new Square (5.2 , "my test square" )test.area test.simpleDescription
# Checking Type
# Swift
1 2 3 4 5 6 7 8 9 10 var movieCount = 0 var songCount = 0 for item in library { if item is Movie { ++ movieCount } else if item is Song { ++ songCount } }
# Go
1 2 3 4 5 6 7 8 9 10 var movieCount = 0 var songCount = 0 for _, item := range (library) { if _, ok := item.(Movie); ok { movieCount++ } else if _, ok := item.(Song); ok { songCount++ } }
# C#
1 2 3 4 5 6 7 8 9 10 var movieCount = 0 ;var songCount = 0 ;foreach (var item in library) { if (item.GetType() == typeof (Movie)) { ++movieCount; } else if (item.GetType() == typeof (Song)) { ++songCount; } }
# SCALA
1 2 3 4 5 6 7 8 9 10 var movieCount = 0 var songCount = 0 for (item <- library) { if (item.isInstanceOf[Movie ]) { movieCount += 1 } else if (item.isInstanceOf[Song ]) { songCount += 1 } }
# Pattern Matching
# Swift
1 2 3 4 5 6 7 8 let nb = 42 switch nb { case 0 ... 7 , 8 , 9 : print ("single digit" ) case 10 : print ("double digits" ) case 11 ... 99 : print ("double digits" ) case 100 ... 999 : print ("triple digits" ) default : print ("four or more digits" ) }
# C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var nb = 42 ;switch (nb){ case int r when (1 <= r && r <= 9 ): Console.WriteLine ("single digit" ) ; break ; case 10 : Console.WriteLine("double digits" ); break ; case int r when (11 <= r && r <= 99 ):x Console.WriteLine ("double digits" ) ; break ; case int r when (100 <= r && r <= 999 ): Console.WriteLine ("triple digits" ) ; break ; default : Console.WriteLine("four or more digits" ); }
# SCALA
1 2 3 4 5 6 7 8 9 10 11 12 13 var movieCount = 0 var songCount = 0 for (item <- library) { item match { case movie: Movie => movieCount += 1 println(s"Movie: '${movie.name} ', dir. ${movie.director} " ) case song: Song => songCount += 1 println(s"Song: '${song.title} '" ) } }
# Downcasting
# Swift
1 2 3 4 for object in someObjects { let movie = object as Movie print ("Movie: '\(movie.name) ', dir. \(movie.director) " ) }
# Go
1 2 3 4 for object := range someObjects { movie := object.(Movie) fmt.Printf("Movie: '%s', dir. %s" , movie.name, movie.director) }
# C#
1 2 3 4 5 6 for (current in someObjects) { if ((current as Movie) != null ) { Console.WriteLine($"Movie: '{(current as Movie).name} '," + $"dir. {(current as Movie).director} " ) } }
# SCALA
1 2 3 4 for (obj <- someObjects) { val movie = obj.asInstanceOf[Movie ] println(s"Movie: '${movie.name} ', dir. ${movie.director} " ) }
# Protocol
# Swift
1 2 3 4 5 6 7 protocol Nameable { func name () -> String } func f <T : Nameable >(x : T ) { print ("Name is " + x.name()) }
# Go
1 2 3 4 5 6 7 type Nameabler interface { func Name () string } func F (x Nameabler) { fmt.Println("Name is " + x.Name()) }
# C#
1 2 3 4 5 6 7 public interface Nameable { string Name ( ) ; } void F (Nameable x ) { Console.WriteLine("Name is " + x.Name()); }
# SCALA
1 2 3 4 5 6 7 trait Nameable { def name (): String } def f [T <: Nameable ](x: T ) = { println("Name is " + x.name()) }
# Extensions
# Swift
1 2 3 4 5 6 7 8 9 10 11 12 13 extension Double { var km: Double { return self * 1_000.0 } var m: Double { return self } var cm: Double { return self / 100.0 } var mm: Double { return self / 1_000.0 } var ft: Double { return self / 3.28084 } } let oneInch = 25.4 .mmprint ("One inch is \(oneInch) meters" )let threeFeet = 3 .ftprint ("Three feet is \(threeFeet) meters" )
# Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type double float64 func (d double) km () double { return d * 1000 }func (d double) m () double { return d }func (d double) cm () double { return d / 100 }func (d double) mm () double { return d / 1000 }func (d double) ft () double { return d / 3.28084 }func main () { var oneInch = double(25.4 ).mm() fmt.Printf("One inch is %v meters\n" , oneInch) var threeFeet = double(3 ).ft() fmt.Printf("Three feet is %v meters\n" , threeFeet) }
# C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public static double mm (this double value ) { return value / 1000 ; } public static double ft (this double value ) { return value / 3.28084 ; } var oneInch = 25.4 .mm();Console.WriteLine($"One inch is {oneInch} meters" ) var threeFeet = 3.0 .ft();Console.WriteLine($"Three feet is {threeFeet} meters" )
# SCALA
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 object Extensions { implicit class DoubleUnit (d: Double ) { def km : Double = { return d * 1000.0 } def m : Double = { return d } def cm : Double = { return d / 100.0 } def mm : Double = { return d / 1000.0 } def ft : Double = { return d / 3.28084 } } } import Extensions .DoubleUnit val oneInch = 25.4 .mmprintln(s"One inch is $oneInch meters" ) val threeFeet = 3. ftprintln(s"Three feet is $threeFeet meters" ) object Extensions { implicit class DoubleUnit (d: Double ) { def km = d * 1000.0 def m = d def cm = d / 100.0 def mm = d / 1000.0 def ft = d / 3.28084 } } import Extensions .DoubleUnit val oneInch = 25.4 .mmprintln(s"One inch is $oneInch meters" ) val threeFeet = 3. ftprintln(s"Three feet is $threeFeet meters" )