Swift或将吸引.NET程序员转向iOS开发

标签: ios Swift C#
发布时间: 2014/12/23 15:48:57

简介

今年开发者大会上,苹果宣布了一个作为ISO和苹果本未来开发语言的新的编程语言--swift。对苹果的追随者来说,这确 实是一个极大的惊喜。经过四年的研发,今天,苹果揭示了为iOS和苹果本下一代应用而设计的基石。Swift遵循了三个设计原则:安全,现代化语法以及强 大的功能。检视该语言后,我发现可以用开发C#的方式进行swift开发,这点尤其让我吃惊。稍后我将概要展示一下swift和C#特性的对比,以便C# 程序员可以迅速理解swift语言都提供什么特性。

背景

很多程序员一直梦想创建iOS应用,但是从头学习objective-C不是易事。但是现在,有了swift,这样就可以不用那么费劲了。Swift中的很多概念都是从我们以前工作中的现代编程语言而来。

Swift 与 C# 非常相似

变量与常量

首先,swift提供类型识别,所以不用强制定义变量类型。编译器可以根据变量内容来确定变量类型。微软在.NET3.0中加入了这个特性,而且该特性也是主流趋势。

SwiftC#, F#

var quantity = 10
var price : Double = 1500.99
let tax = 2.99 // constant
           

var quantity = 10;
double price = 1500.99;
const double tax = 2.99
let tax = 2.99 // F# language
           

在swift中,我们首先会看到句末的分号被干掉了。它用let关键字定义常量,用var关键字定义变量。在C#中,变量可以用var关键字进行声明;在F#中,也用let关键字声明变量。当声明变量时,若没有对其赋值,则需指定变量类型。

SwiftC#

errCode: String
           

string errCode;
           

Swift 引入了选择类型。该类型可以让我们标明变量是有值的还是null。Swift的选择类型提供了编译时校验,这样防止了运行时发生的常见编程错误。一旦我们 知道了选择类型包含值,我们就可以通过在选项名后边放置一个感叹号来打开选择类型。这被称为强制打开。类似于.NET下的声明可为null的变量。

SwiftC#

var findNumber: Int? // Null value
if (findNumber != nil )
    { var searchValue = findNumber! }
           

int? findNumber;
if (findNumber.HasValue)
    { var searchValue = findNumber.Value; }
           

String方法,比如将字符串进行大小写转换、判断起始/终止字符串是否与实例中的字符串匹配也非常相似。

SwiftC#

var strName = "iPhone 6"
if strName.uppercaseString.hasPrefix("IP")
    {    // to do     }
if strName.lowercaseString.hasSuffix("6")
    {   // to do      }
           
var strName = "iPhone 6";
if (strName.ToUpper().StartsWith("IP"))
    {     //to do    }
if (strName.ToLower().EndsWith("6"))
    {     //to do     }
           

Swift另一个受欢迎的特性是string的模板。该模板可以用来构造一个字符串。具体方法为用“\()”装载含有变量的要计算的表达式。C#则是通过使用string.Format来实现同样效果。

SwiftC#
var total = "Total: \(price * Double(quantity))"
           
var total = String.Format ("Total {0}", price * quantity);
         

数组

Swift中定义数组的语法和C#稍有不同。但是有类似的功能。一些方法的实现都是相同的。我们可以逐行对比下面的例子:

SwiftC#

var arrayItem: [String] =  ["iPhone","iPad"]
// for-in loop
for item in arrayItem {   // to do     }
// check  empty
if arrayItem.isEmpty {    // to do   }
// Get item by index
var first = arrayItem[0]
// Set item by index
arrayItem[0] = "Macbook"
// remove item
arrayItem.removeAtIndex(0)
           
var arrayItem = new string[] { "iPhone", "iPad" };
// for-each loop
foreach (var item in arrayItem)    { // to do }
// check  empty
if (arrayItem.Length == 0)   { // to do   }
// Get item at index
var first = arrayItem[0]
// Set item by index
arrayItem[0] = " Macbook "
// remove item
var list = arr.ToList();
list.RemoveAt(0);

就像变量一样,数组被强制定义为默认类型,在这一点上swift颇类似javascript.

SwiftC#
var arrayItem  =  ["iPhone","iPad"]
var arrayItem  =  ["iPhone","iPad"];

在我看来,swift的数组极像C#中的list.

Dictionary

C#和Swift有着非常相似的方法,但是声明和迭代式略有不同,而这点区别几乎可以忽略不计。下面的表格描述了Swift和C#中字典的方法.

SwiftC#
var listItem: Dictionary<int, string=""> =
     [1: "iPhone", 2: "iPad"]
// Iterate dictionary
for (key, value) in listItem
    {   // todo key and value   }
// set item to dictionary
listItem[3] = "Macbook"
// Remove item out dictionary by key
listItem.removeValueForKey(2)
// Get item from dictionary by key
var first = listItem[1]
var listItem = new Dictionary<int, string>()
    {{1, "iPhone"}, {2, "iPad"}};
// Iterate dictionary
foreach (var item in listItem)
   { // todo item.key and item.value     }
// set item to dictionary
listItem[3]="Macbook";
// Remove item out dictionary by key
listItem.Remove(2);
// Get item from dictionary by key
var first = listItem[1];

我们可以可以通过设置null值来移除swift中字典的项Listitem[2]= nil ,在这点上和javascript比较类似.

If 条件语句

Swift 不需要圆括号“()”括住对比条件。参数是可选的,但是if  表达式必须以成对的大括号“{}”开始和结束。即使只有一条if语句。在C#中if表达式若只有一句,则可以不用大括号括住表达式。这样做的原因是苹果想 让swift更加安全,避免出现异常错误,比如苹果之前遇到的SSL "goto fail"这个错误:

if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
        goto fail;
        goto fail;  /* MISTAKE! THIS LINE SHOULD NOT BE HERE */

“ goto fail”调用了两次。这个bug看起来是因为程序员复制粘贴引起的,但是小bug可能引起毁灭性错误。下面的例子对比了swift和C#中的 if 条件语句:

SwiftC#
if searchItem  == "iPhone" // don't need ()
    {   vat = 1.99   } // must have  {}
else if searchItem  == "iPad"
    {    //todo   }
else
    {   //todo    }
if (searchItem  == "iPhone")
   vat = 1.99 ; // Don’t need  {}
else if (searchItem  == "iPad")
   {  //todo    }
else
   {   //todo     }

Switch 语句

Swift中的Switch 语句和C#的语法也极其相似。但是在swift中“break”表达式不是必须的而且default子句是必须的.

SwiftC#
switch index {
    case 0: // to do
    case 1: // to do
    default: // it is mandatory.
}
  
switch (index) {
    case 0: break ;// to do
    case 1: break ;// to do
    default: break;
}

Swift中的Case 语句支持多个条件。就这点来说,它比C#更简单.

SwiftC#
switch index {
    case 0, 1: //  multiple value
    case 2...10: // multiple value
    default: // todo }
switch (index) {
    case 0:
    case 1:
    break;  // todo
    default: break; }

for – while – do … while

Swift提供 for, while 和 do-while 循环语句,其语法与C#类似。幸运的是语法上没有重大改变,只是swift中循环语句的条件不需要圆括号括起来。

SwiftC#
// For loop
for var i = 0 ; i < 100 ; ++i  {  // to do  }
 // while
while !done  {  // to do  }
// do .. while
do  {   // to do  } while !done
// for in range
for index in 1...5  {  // to do   }
// For loop
for(var i = 0; i < 100; i++) {  // to do  }
// while
while !done  {  // todo  }
// do .. while
do  {  // todo } while !done
// for in range
foreach (var i in Enumerable.Range(1, 5)) 
    {  // to do   }

方法

与C#类似,方法是swift的首级成员。亦即swift允许我们做很多有用的处理,比如可以被存储到变量或常量中,作为参数传递,指定给变量或作为另一个方法的返回结果。就方法而言,swift和C#基本没有区别。

SwiftC#
func Total(quantity: Int, price: Double) -> Double {
    return Double(quantity) * price     }
// Multiple return values
func getDetail() -> 
    (name:String,quantity: Int, price :Double)
    {  return ("iPhone6",2, 1500.99)   }
// in Out parameter
func swapNumbers(inout a: Int, inout b: Int)
    { var  c = a;  a = b;   b = c; }
// Function Type
var result : (Int, Double) -> Double = Total
//or
var result -> Double = Total
double Total(int quantity, double price)
        {     return quantity * price;   }
// Multiple return values
Tuple<string, int, double> getDetail()
  {  return new Tuple<string,int ,
  double>("iPhone6", 2, 1500.99);   }
// in Out parameter
void swapNumbers (ref int a, ref int b)
   { var c = a; a = b; b = c; }
// Function Type
Func<int, double, double> result = Total;

由于swift和C#都支持将方法作为参数进行传递,方法作为返回类型等等。我们可以看到这个基本语法二者比较相似。参照以上对比你可以发现二者并无太大区别。

协议

在C#中我们接触过接口。Swift中的协议和c#的接口比较像。协议时译注方法和属性的封装体,且不实现任何内容。协议只是定义需要的属性和方法。任何使用该协议的类必须实现方法并制定属性值。协议可以降低类的耦合。

SwiftC#
protocol Purchase
{
    var name : String { get  set};
    var quantity : Int { get  set};
    var price : Double { get  set};
    func Total() -> Double;
}
interface Purchase
{
    string name { get;  set;}
    int quantity  { get;  set;}
    double price { get;  set;}
    double total();
}

下边的列表描述了如何创建C#和swift中的类:

SwiftC#
class ItemDetail {
    var itemName : String
    var itemQuantity : Int
    var itemPrice : Double
    init(name: String, quantity: Int, price:Double)
     {
        self.itemName = name;
        self.itemQuantity = quantity;
        self.itemPrice = price;
    }
    func Total () -> Double {
        return itemPrice * Double(itemQuantity)
      }
}
// Access class
var itemDetail =
      ItemDetail (name:"iPhone", 
      quantity: 2, price: 100.99)
public  class ItemDetail {
    private string itemName;
    private int itemQuantity;
    private double itemPrice;
    public ItemDetail  
        (string name, int  quantity,
        double price)    {
        itemName = name;
        itemQuantity = quantity;
        itemPrice = price;
        }
    public double Total ()   {
       return itemPrice * itemQuantity;
          }
}
//  Access class
ItemDetail iTemDetail =
    new ItemDetail ("phone", 1, 1.2);

Swift和c#定义属性、方法和构造函数的方式并无区别。二者的区别小到可以忽略不计。C#开发人员可以快速学习该语言。二者同样支持子类。但是我更想展示一下swift类如何使用协议和实现协议的属性、方法。

class iPhone : Purchase {
    var name = "iPhone"
    var quantity =  1
    var price = 1500.99
    func Total () -> Double {
        return price * Double(quantity)
    }
}

这种方式和我们在c#中实现接口非常相似。

扩展

Swift的强大之处在于它支持向现有的类、结构体或者枚举类型追加新的方法。这个特性和c#bijiao类似。下面的demo通过扩展 Max, Min 和 Average 方法,描述了如何扩展c#和swift中的数组:

SwiftC#
extension Array {
    var Min: T { // to do }
    var Max: T { // to do }
    var Average: T { // to do }
    }
// call extension
var max = arrayNumber.Max
public static  class ArrayExtension
    public static T Max<T>(T[] arr)    { // to do }
    public static T Min<T>(T[] arr)   { // to do }
    public static T Average<T>(T[] arr)  { // to do }
}
// call extension
var max = ArrayExtension.Max(arr);

闭包

闭包可实现将一个方法和其上下文打包到一个对象中。这使得阅读和调试代码更加简单。下面的代码展示了如何通过闭包对数据排序。

SwiftC#
var arrayNumber = [4,5,3]
var list = sorted(arrayNumber, { s1, s2 in
    return s1 < s2 })
List<int> list = new List<int> { 4, 5, 3, };
list.Sort((x, y) => Convert.ToInt32((x < y)));

总之,如果我们以前写c#代码,写swift代码会很容易上手。
闭包可以用更少的代码有效表达开发人员更多的意图。就像在使用c#中的闭包一样,理解和使用闭包是一个可以有效开发ios的因素。

泛型

泛型是编写代码强有力的武器。泛型是强类型,且类型可变。Swift基于c#建立了泛型的概念。使用泛型的时候,开发人员可以实现一个对所有类型适用的函数。下面搜索数组/列表的方法展示了如何简单运用泛型:

SwiftC#
func indexArray<T :Equatable>
(item :T, array :[T]) -> T?
    {
        for value in array
        {
            if(value == item)
            {
                return value
            }
        }
         return nil
    }
public static Nullable<T>
IndexList<T>(T item, T[] arr) where T : struct
    {
        foreach (var i in arr)
        if (i.Equals(item))
            {
               return i;
            }
           return null;
       }

实际上,以上代码显示我们可以像使用c#一样使用swift。Swift仅有小量语法的改动。

兴趣点

Swift和c#有很多相似之处。我们可以在使用swift开发ios的过程中,使用我们现有的技巧和知识。更重要的是,swift的的语法更易于使用,尤其对有.NET开发背景的人而言。

Swift 并不是终极产品,苹果一直在完善swift。貌似几个月后还有新的特性会添加进来。它绝对值得你熟悉一下。



赞助商