The Swift Programming Language实验项目相关解决方案

发布于:2014-07-03 17:44阅读数:

《The Swift Programming Language》第一章节“A Swift Tour”中,有各种各样的试验需要你去“解决”用来阐述指南中示例的代码问题。苹果并没有给我们提供相关的实际解决方案,所以在此列出了我们想

苹果的Swift编程语言是由Chris Lattner在2010年7月开始主导开发的,在2014年6月2日的苹果全球开发者大会上正式发布。Swift语言的第一个官方资源是苹果的官方文档《The Swift Programming Language》。读了它的第一章节“Swift初见(A Swift Tour)”,有各种各样的试验需要你去“解决”用来阐述指南中示例的代码问题。苹果并没有给我们提供相关的实际解决方案,所以在此列出了我们想到的一些。

 
书中列出的每个问题,我们都在下边给了出解决方案。当然,每个问题也可以有其它解决方案。
 
 
GithubTwitter上可查看更多示例和免费内容。
 
想通过视频去一步步了解Swift的更多细节吗?可以订阅SwiftCast,成为Swift专家。
 
实验1:创建一个显式浮点类型常量,并赋值4。
  1. let explicitFloat: Float = 4.00 
 
实验2:删除最后一行中的转化为字符串的代码S。错误提示是什么?
  1. let label = "The width is" 
  2. let width = 94  
  3. // error: Could not find an overload for '+' that accepts supplied arguments 
产生这个错误的原因是Int隐式类型的宽度,它不能用隐式类型的标签常量相关联,它是隐式类型的String。
 
实验3:使用\()把一个浮点运算包含在一个字符串内,并在greeting中加上某个人的名字
  1. //3a: Floating point calculation 
  2. let revenue: Float = 160.0 
  3. let cost: Float = 70.0 
  4. let profit: String = "Today my lemonade stand made \(revenue-cost) dollars of profit" 
  5.  
  6. //3b: Use someone's name in a greeting 
  7. let personsName: String = "Josh" 
  8. let greetJosh = "Hi \(personsName)" 
 
实验4:把optionalName改为nil。你得到的greeting会是什么?添加一个else分句,在optionalName是nil时给greeting设置一个问候语。
  1. // 4a: Change optionalName to nil 
  2. var optionalName: String? = "John Appleseed" 
  3. var greeting = "Hello!" 
  4.  
  5. optionalName = nil 
  6.  
  7. if let name = optionalName { 
  8.     greeting = "Hello, \(name)" 
  9.  
  10. // 4b: Add an else clause that sets a different greeting if optionalName is nil 
  11. if let name = optionalName { 
  12.     greeting = "Hello, \(name)" 
  13. else { 
  14.     greeting = "Hello stranger" 
 
实验5:删除default语句,会出现什么错误?
  1. let vegetable = "red pepper" 
  2.  
  3. switch vegetable { 
  4. case "celery"
  5.     let vegetableComment = "Add some raisins and make ants on a log." 
  6. case "cucumber""watercress"
  7.     let vegetableComment = "That would make a good tea sandwich." 
  8. case let x where x.hasSuffix("pepper"): 
  9.     let vegetableComment = "Is it a spicy \(x)?" 
  10. default
  11.     let vegetableComment = "Everything tastes good in this soup" 
  12.  
  13. // error: switch must be exhaustive, consider adding a default case 
在转换之前如果我们声明了vegetableComment常量,那么就无需default语句,因为它的默认值已经被声明了。
 
实验6:添加另一个变量来记录哪种类型的数字是最大的,以及最大值是多少。
  1. let interestingNumbers = [ 
  2.     "Prime": [2, 3, 5, 7, 11, 13], 
  3.     "Fibonacci": [1, 1, 2, 3, 5, 8], 
  4.     "Square": [1, 4, 9, 16, 25], 
  5. var largest = 0 
  6. var largestKind: String = "" 
  7.  
  8. for (kind, numbers) in interestingNumbers { 
  9.     for number in numbers { 
  10.         if number > largest { 
  11.             largest = number 
  12.             largestKind = kind 
  13.         } 
  14.     } 
  15.  
  16. largest 
  17. largestKind 
 
实验7:删除day参数,在greeting中添加一个参数来包含今天的午餐。
  1. func greet(name: String, todaysLunch: String) -> String { 
  2.     return "Hello \(name), today's lunch is \(todaysLunch)." 
  3.  
  4. greet("Bob""Turkey Sandwich"
 
实验8:写一个计算参数平均值的函数
  1. func average (numbers: Int...) -> Int { 
  2.     var sum = 0 
  3.  
  4.     for number in numbers { 
  5.         sum += number 
  6.     } 
  7.  
  8.     return sum/numbers.count 
  9.  
  10. average(2, 10) 
 
实验9:重写闭包,对所有奇数返回0
  1. var numbers = [20, 19, 7, 12] 
  2.  
  3. numbers.map({ 
  4.     (number: Int) -> Int in 
  5.         if number % 2 == 0 { 
  6.             return number 
  7.         } 
  8.         else { 
  9.             return 0 
  10.         } 
  11. }) 
 
实验10:用let添加一个常量属性,并添加一个接收参数的方法。
  1. class Shape { 
  2.     var numberOfSides = 0 
  3.     let dimension = "2d" 
  4.  
  5.     func simpleDescription() -> String { 
  6.         return "A shape with \(numberOfSides) sides." 
  7.     } 
  8.     func notSoSimpleDescription() -> String { 
  9.         return "This is a \(dimension) shape." 
  10.     } 
  11.  
  12. let myShape = Shape() 
  13. myShape.notSoSimpleDescription() 
 
实验11:创建NamedShape的另一个名为Circle的子类,该子类可接收两个参数:半径和名称来作为其initializer参数。实现Circle类的area和describe方法。
  1. class NamedShape { 
  2.   var numberOfSides: Int = 0 
  3.   var name: String 
  4.  
  5.     // The initializer method is the entry point to our class. Upon creating an instance, this method will be called, which requires us to pass the arguments it expects on instantiation. 
  6.  
  7.     init(name: String) { 
  8.  
  9.     // Name is a local variable, meaning it's only available via the context of this method. We can assign it to an instance variable with the call to self.name = name. This allows us to call .name on our instance of NamedShape class to retrieve the value. 
  10.         self.name = name 
  11.     } 
  12.  
  13.     func simpleDescription() -> String { 
  14.         return "A shape with \(numberOfSides) sides." 
  15.     } 
  16.  
  17. class Circle: NamedShape { 
  18.     var radius: Double 
  19.  
  20.     init (name: String, radius: Double) { 
  21.         self.radius = radius 
  22.  
  23.         super.init(name: name) 
  24.  
  25.         self.name = name 
  26.     } 
  27.  
  28.     override func simpleDescription() -> String { 
  29.         return "A circle with a radius of \(radius)" 
  30.     } 
  31.  
  32.     func area() -> Double { 
  33.         return 3.14159265 * radius * radius 
  34.     } 
  35.  
  36. let myCircle = Circle(name: "Example circle", radius: 6.0) 
  37.  
  38. myCircle.name 
  39. myCircle.area() 
  40. myCircle.simpleDescription() 
 
实验12:写一个函数,通过比较它们的原始值来比较两个Rank值
  1. enum Rank: Int { 
  2.     case Ace = 1 
  3.     case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten 
  4.     case Jack, Queen, King 
  5.  
  6.     func simpleDescription() -> String { 
  7.         switch self { 
  8.         case .Ace: 
  9.             return "ace" 
  10.         case .Jack: 
  11.             return "jack" 
  12.         case .Queen: 
  13.             return "queen" 
  14.         case .King: 
  15.             return "king" 
  16.         default
  17.             return String(self.toRaw()) 
  18.         } 
  19.     } 
  20.  
  21. let ace = Rank.Ace 
  22. let two = Rank.Two 
  23. let aceRawValue = ace.toRaw() 
  24.  
  25. func compare(rank1: Rank, rank2: Rank) -> String { 
  26.     var higher: Rank = rank1 
  27.     if rank2.toRaw() > rank1.toRaw() { 
  28.         var higher = rank2 
  29.     } 
  30.     return "The higher of the two is \    (higher.simpleDescription())" 
  31.  
  32. compare(ace, two) 
 
实验13:给Suit添加一个color方法,并为spades和clubs返回“black”,给hearts和diamonds返回“red”
  1. enum Suit: Int { 
  2.     case Spades = 1 
  3.     case Hearts, Diamonds, Clubs 
  4.  
  5.     func simpleDescription() -> String { 
  6.         // When we pass self to switch, self is in the context of the enum. Here meaning Suit. Passing self allows us to access the properties of the enum with the dot notation and doesn't require us to have to use Suit.Spades. 
  7.         switch self { 
  8.           case .Spades: 
  9.               return "spades" 
  10.           case .Hearts: 
  11.               return "hearts" 
  12.           case .Diamonds: 
  13.               return "diamonds" 
  14.           case .Clubs: 
  15.               return "clubs" 
  16.         } 
  17.     } 
  18.  
  19.     func color() -> String { 
  20.         switch self { 
  21.         case .Spades, .Clubs: 
  22.             return "black" 
  23.         case .Hearts, .Diamonds: 
  24.             return "red" 
  25.         } 
  26.     } 
  27.  
  28. let heartsDescription = Suit.Hearts.simpleDescription() 
  29. let heartsColor = Suit.Hearts.color() 
 
实验14:给Card添加一个方法,创建一副完整的扑克牌,并把每张牌的rank和suit联系起来。
  1. class Card { 
  2.     var rank: Rank 
  3.     var suit: Suit 
  4.  
  5.     init(cardRank: Rank, cardSuit: Suit) { 
  6.         self.rank = cardRank 
  7.         self.suit = cardSuit 
  8.     } 
  9.  
  10.     func simpleDescription() -> String { 
  11.         return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" 
  12.     } 
  13.     // To get a full deck we need to loop through all the ranks, assign each suit and put those into an array. The rank has a int raw value so we can use that. 
  14.     func Deck() -> String { 
  15.         var stringTogether = "" 
  16.  
  17.         for i in 0..14 { 
  18.             if let convertedRank = Rank.fromRaw(i) { 
  19.                 self.rank = convertedRank 
  20.  
  21.                 for y in 0..5 { 
  22.                     if let convertedSuit = Suit.fromRaw(y) { 
  23.                         self.suit = convertedSuit 
  24.                         stringTogether = "\(stringTogether) \(self.simpleDescription())" 
  25.                     } 
  26.                 } 
  27.             } 
  28.         } 
  29.         return stringTogether 
  30.     } 
  31.  
  32. let threeOfSpades = Card(cardRank: .Three, cardSuit: .Spades) 
  33. let threeOfSpadesDescription = threeOfSpades.simpleDescription() 
  34. threeOfSpades.Deck() 
 
实验15:给ServerResponse协议添加三个实例。
  1. enum ServerResponse { 
  2.     case Result(String, String) 
  3.     case Error(String) 
  4.     case ThirdCase(String) 
 
实验16:写一个符合该协议的枚举。
  1. protocol ExampleProtocol { 
  2.     var simpleDescription: String { get } 
  3.     mutating func adjust() 
  4.  
  5. class SimpleClass: ExampleProtocol { 
  6.     var simpleDescription: String = "A very simple class." 
  7.     var anotherProperty: Int = 69105 
  8.  
  9.     func adjust() { 
  10.         simpleDescription += "  Now 100% adjusted." 
  11.     } 
  12.  
  13. class ConformingClass: ExampleProtocol { 
  14.     var simpleDescription: String = "A very simple class." 
  15.     var carModel: String  = "The Toyota Corolla" 
  16.  
  17.     func adjust() { 
  18.         carModel += " is the best car ever" 
  19.     } 
  20.  
  21. let conformingClass = ConformingClass() 
  22. conformingClass.adjust() 
  23.  
  24. let whichCarIsBest = conformingClass.carModel 
 
实验17:编写一个添加了一个绝对值属性的Double类型扩展。
  1. extension Double { 
  2.     var absoluteValue: Double { 
  3.         return abs(self) 
  4.     } 
  5.  
  6. let exampleDouble: Double = -40.0 
  7. let exampleAbsoluteValue = exampleDouble.absoluteValue 
 
实验18:修改anyCommonElements函数来创建一个函数,该函数返回一个包含两个序列相同元素的数组。
  1. func anyCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Bool { 
  2.     for lhsItem in lhs { 
  3.         for rhsItem in rhs { 
  4.             if lhsItem == rhsItem { 
  5.                 return true 
  6.             } 
  7.         } 
  8.     } 
  9.  
  10.     return false 
  11.  
  12. anyCommonElements([1, 2, 3], [3]) 
  13.  
  14. func whichCommonElements <T, U where T: Sequence, U: Sequence, T.GeneratorType.Element: Equatable, T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) -> Array<T.GeneratorType.Element> { 
  15.     var toReturn = Array<T.GeneratorType.Element>() 
  16.  
  17.     for lhsItem in lhs { 
  18.         for rhsItem in rhs { 
  19.             if lhsItem == rhsItem { 
  20.                 toReturn.append(lhsItem) 
  21.             } 
  22.         } 
  23.     } 
  24.  
  25.     return toReturn 
  26.  
  27. whichCommonElements([1, 2, 3], [3, 2]) 
我希望这些例子对你有用。如果有任何问题,请留言。
 

CocoaChina是全球最大的苹果开发中文社区,官方微信每日定时推送各种精彩的研发教程资源和工具,介绍app推广营销经验,最新企业招聘和外包信息,以及Cocos2d引擎、Cocos Studio开发工具包的最新动态及培训信息。关注微信可以第一时间了解最新产品和服务动态,微信在手,天下我有!

请搜索微信号“CocoaChina”关注我们!

搜索CocoaChina微信公众号:CocoaChina

顶部