//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
let emptyArr = [String]();
let emptyDictionary=[String:Float]()
var optionalName = [1,2,3,4,5,6]
var optionalNames:String?="John Appleaeed"
if let name = optionalNames{
var greeting = "hello \(name)"
}
func sumOf(numbers:Int...)->Int{
var sum = 0
for number in numbers{
sum += number
}
return sum
}
sumOf()
sumOf(1,2,3)
func hasAnyMatches(List:[Int],contion:Int->Bool)->Bool{
for item in List{
if contion(item){
return true;
}
}
return false
}
func lessThanTen(number:Int)->Bool{
return number<10;
}
var numbers=[12,19,7,12];
hasAnyMatches(numbers, contion: lessThanTen)
//“你可以使用{}来创建一个匿名闭包,使用in将参数和返回值类型声明与闭包函数体进行分离”
numbers.map({
(number:Int)->Int in
let result = 3*number
return result
})
numbers.map({
(number:Int)->Int in
var result = number
if(number%2==1){result=0}
print(result)
return result
})
class Shape {
var numberOfSide = 0
func simpleDescription()->String{
return "A shape with\(numberOfSide) sides."
}
}
var shape = Shape()
shape.numberOfSide = 7
var shapeDescription = shape.simpleDescription()
class NamedShape {
var numberOfSides :Int = 0
var name:String
init(name:String){
self.name = name
}
func simpleDescription()->String{
return "A simple with\(numberOfSides)sides"
}
deinit{
print("name deinit")
}
}
class Square: NamedShape {
var sideLength:Double
init(sideLength:Double,name:String){
self.sideLength = sideLength
super.init(name: name)
}
func area()->Double{
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A squqre sides of length\(sideLength)"
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
class EquilateralTriangle: NamedShape {
var sideLength :Double = 0.0
init(sideLength:Double,name:String){
self.sideLength = sideLength
super.init(name: name )
numberOfSides = 3
}
var perimeter :Double{
get{
return 3*sideLength
}
set{
sideLength = newValue/3.0
}
// willSet{
// sideLength
// }
// didSet{
// sideLength = 4
// }
}
override func simpleDescription() -> String {
return "A squqre sides of length\(sideLength)"
}
}
//“如果你不需要计算属性,但是仍然需要在设置一个新值之前或者之后运行代码,使用willSet和didSet”
var triangle = EquilateralTriangle(sideLength: 3.1, name: "A triangle")
print(triangle.perimeter)
triangle.perimeter = 9.9
print(triangle.sideLength)
class TriangleAndSquare{
var triangle:EquilateralTriangle{
willSet{
square.sideLength = newValue.sideLength
}
}
var square:Square{
willSet{
triangle.sideLength = newValue.sideLength
}
}
init(size:Double,name:String){
square = Square(sideLength:size,name:name)
triangle = EquilateralTriangle(sideLength:size,name:name)
}
}
var triangleAndSquare=TriangleAndSquare(size:10,name:"another test shape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square=Square(sideLength:50,name:"larger square")
print(triangleAndSquare.triangle.sideLength)
let optionalSquare:Square? = Square(sideLength:2.5,name:"optional square")
let sideLength = optionalSquare?.sideLength
/**
“在上面的例子中,枚举原始值的类型是Int,所以你只需要设置第一个原始值。剩下的原始值会按照顺序赋值。你也可以使用字符串或者浮点数作为枚举的原始值。使用rawValue属性来访问一个枚举成员的原始值”
*/
enum Rank:Int{
case Ace = 1
case Two,Three,Four,Five,Seven,Eight,Nine,Ten
case Jack,Queen,King
func simpleDescription()->String{
switch self{
case .Ace:
return "ace"
case .Jack:
return "Jace"
case .Queen:
return "queue"
case .King:
return "King"
default:
return String(self.rawValue)
}
}
}
// 使用init?(rawValue:)初始化构造器在原始值和枚举值之间进行转换。
let ace = Rank.Ace
let aceRawValue = ace.rawValue;
if let convertedRank=Rank(rawValue:3){
let threeDescription=convertedRank.simpleDescription()
}
/**
枚举的成员值是实际值,并不是原始值的另一种表达方法。实际上,以防原始值没有意义,你不需要设置
*/
enum Suit{
case Spades,Hearts,Diamonds,Clubs
func simpleDescription()->String{
switch self {
case.Spades:
return "spades"
case.Hearts:
return "hearts"
case.Diamonds:
return "diamonds"
case.Clubs:
return "clubs"
}
}
}
let hearts = Suit.Hearts
struct Card{
var rank:Rank
var suit:Suit
func simpleDescription()->String{
return "The\(rank.simpleDescription())of\(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank:.Three,suit:.Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
/**
一个枚举成员的实例可以有实例值。相同枚举成员的实例可以有不同的值。创建实例的时候传入值即可。
实例值和原始值是不同的:枚举成员的原始值对于所有实例都是相同的,而且你是在定义枚举的时候设置原始值。
例如,考虑从服务器获取日出和日落的时间。服务器会返回正常结果或者错误信息”
*/
enum ServerResponse{
case Result(String,String)
case Error(String)
}
let success = ServerResponse.Result("6.00", "9.00")
let frilure = ServerResponse.Error("out of cheese")
switch frilure{
case let .Result(sunrise,sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)"
case let .Error(error):
let serverResponse = "Failure ...\(error)"
}
/**
* 使用protocol来声明一个协议”
*/
protocol ExampleProtocol{
var simpleDescription :String {get}
mutating func adjust()
}
/**
* 类、枚举和结构体都可以实现协议
*/
class SimpleClass: ExampleProtocol {
var simpleDescription:String = "a simple class"
var anotherProperty:Int = 8888
func adjust() {
simpleDescription += "Now 100% adjusted"
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
/**
* “mutating关键字用来标记一个会修改结构体的方法”
*/
struct SimpleStrure:ExampleProtocol {
var simpleDescription:String = "a simple structure"
mutating func adjust() {
simpleDescription += "(adjusted)"
}
}
var b = SimpleStrure()
b.adjust()
let bDescription = b.simpleDescription
/**
* “使用extension来为现有的类型添加功能,比如新的方法和计算属性。你可以使用扩展在别处修改定义,甚至是从外部库或者框架引入的一个类型,使得这个类型遵循某个协议”
“你可以像使用其他命名类型一样使用协议名——例如,创建一个有不同类型但是都实现一个协议的对象集合。当你处理类型是协议的值时,协议外定义的方法不可用”
*/
extension Int:ExampleProtocol{
var simpleDescription :String { return "The number \(self)"}
mutating func adjust() {
self += 43
}
}
// “即使protocolValue变量运行时的类型是simpleClass,编译器会把它的类型当做ExampleProtocol。这表示你不能调用类在它实现的协议之外实现的方法或者属性”
let protocolValue :ExampleProtocol = a
print(protocolValue.simpleDescription)
/**
* “在尖括号里写一个名字来创建一个泛型函数或者类型”
*/
func repeatItem<Item>(item:Item,numberOfTimes:Int)->[Item]{
var result = [Item]()
for _ in 0..<numberOfTimes{
result.append(item)
}
return result
}
repeatItem("knock",numberOfTimes:4)
/**
* “你也可以创建泛型函数、方法、类、枚举和结构体”
*/
enum OptionalValue<Wrapped>{
case None
case Some(Wrapped)
}
var possibleInteger:OptionalValue<Int> = .None
possibleInteger = .Some(100)
/**
“在类型名后面使用where来指定对类型的需求,比如,限定类型实现某一个协议,限定两个类型是相同的,或者限定某个类必须有一个特定的父类”
“<T: Equatable>和<T where T: Equatable>是等价的”
*/
func anyCommonElements <T:SequenceType,U:SequenceType where T.Generator.Element:Equatable,T.Generator.Element==U.Generator.Element>(lhs:T,rhs:U)->Bool{
for lhsItem in lhs{
for rhsItem in rhs{
if lhsItem==rhsItem{
return true
}
}
}
return false
}
anyCommonElements([1,2,3],rhs: [1])