//Inheritance, override, final
class Vehicle{
var totalVehicles : Int = 0
var desc:String {
return "totalVehicles : \(totalVehicles)."
}
}
class Bycle: Vehicle {
override init(){
super.init()
self.totalVehicles = 2
}
override var desc : String {
return super.desc + ", in bycle"
}
final func noOverrideMethod(){
print("final keyword mean this cannot be allowed to override any more")
}
}
class Bycle4Wheels : Bycle {
override init(){
super.init()
self.totalVehicles = 4
}
override var desc : String {
return super.desc + " with 4 wheels "
}
}
var b = Bycle()
print( b.desc)
b.noOverrideMethod()
var f = Bycle4Wheels()
print( f.desc)
2017년 2월 18일 토요일
Swift Inheritance, override, final
//Inheritance, override, final
Swift Instance Method, Type Method,subscript
struct StructSample{
static func typeMethod(){
print("i am type method")
}
func instanceMethod(){
print("i am instance method")
}
}
var s = StructSample()
s.instanceMethod()
StructSample.typeMethod()
class ClassSample{
//class keyword allow subclasses to override superclass implements
class func typeMethod(){
print("i am type method")
}
//static keyword not allow subclasses to override superclass implements
static func staticTypeMethod(){
print(" static method from statcTypeMechod")
}
func instanceMethod(){
print("i am instance method")
}
}
var c = ClassSample()
c.instanceMethod()
ClassSample.typeMethod()
//static, class modifiers ?
class SomeClass {
class var overrideType: Int {
get {
return 107
}
}
static var type2 : Int {
get {
return 1
}
}
}
print(SomeClass.overrideType)
print(SomeClass.type2)
//subscript
struct SubscriptSample{
var weight : Int
subscript(index:Int) -> Int {
return index * weight
}
}
var s = SubscriptSample(weight:3)
print( s[2],s[3])
2017년 2월 17일 금요일
Swift mutating
Modifying Value Types from Within Instance Methods Structures and enumerations are value types. By default, they cannot be modified from within its instance Methods However, if you want, you can opt in to "mutating" keyword. mutating The mutating keyword is added to its definition to enable it to modify its properties.
struct RectST {
var x : Double = 0
func minus(x dx:Int ){
x -= dx error: Left side of mutating operator isn't mutable: 'self' is immutable
}
mutating func move (x dx:Double){
x += dx
}
mutating func moveSelf(x dx:Double){
self = RectST(x:dx)
}
}
class Rect {
var x : Double = 0
func move (x dx:Double){
x += dx
}
}
var c01 = RectST()
c01.minus(x:3)
c01.move(x:222)
enum TriStateSwitch {
case off,low,high
mutating func next(){
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
Swift Lazy, Computed, Observers Properties
//1. Lazy Stored Properties
class DataImporter {
var fileName = "data.txt"
}
class DataManager {
lazy var importer = DataImporter()
var data = [String]()
}
var m = DataManager()
m.data.append("data 1 ")
m.data.append("data 2 ")
//m.importer has not yet been created.
print( m.importer.fileName )
//m.importer has been created now.
//2. Computed Properties
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
var center : Point {
get {
let tmpx = origin.x + size.width/2
let tmpy = origin.y + size.height/2
return Point(x:tmpx,y:tmpy)
}
// set {
// origin.x = newValue.x - size.width/2
// origin.y = newValue.y - size.height/2
// }
// renaming newCenter as newValue
set ( newCenter ){
origin.x = newCenter.x - size.width/2
origin.y = newCenter.y - size.height/2
}
}
}
var r = Rect(origin:Point(x:10,y:10), size:Size(width:20,height:20))
print( r.center)
// 3. setter, getter
class Test {
var _power : Double = 0.0
var power : Double {
get {
return _power
}
set (newValue){
_power = newValue
}
}
}
/* 4.Property Objservers
willSet is called just before the value is stored.
didSet is called immediately after the new value is stored.”
*/
class Sample {
var force : Int = 0 {
willSet(newV){
print("\(force) -> \(newV)")
}
didSet {
print("\(oldValue) -> \(force)")
}
}
}
var s = Sample()
print(s.force)
s.force = 12
print(s.force)
swift class and struct
Class have additional capablities that sturctures do not
As a general guideline, consider creating a structure when one or more of these conditions apply:
- The structure’s primary purpose is to encapsulate a few relatively simple data values.
- It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
- Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
- The structure does not need to inherit properties or behavior from another existing type. Examples of good candidates for structures include:
- The size of a geometric shape, perhaps encapsulating a width property and a height property, both of type Double.
- A way to refer to ranges within a series, perhaps encapsulating a start property and a length property, both of type Int. - A point in a 3D coordinate system, perhaps encapsulating x, y and z properties, each of type Double.”
- Inheritance enables one class to inherit the characteristics of another.
- Type casting enables you to check and interpret the type of a class instance at runtime.
- Deinitializers enable an instance of a class to free up any resources it has assigned.
- Reference counting allows more than one reference to a class instance.
Structures are always copied when they are passed around in your code, and do not use reference counting.
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var framerate = 0.0
var name: String?
}
var hd = Resolution(width:30,height:100)
var tmpHd = hd
tmpHd.width = 120
//sturct and enumeration are value types
print("sturct \(hd.width) != \(tmpHd.width). copied")
var c = VideoMode()
c.resolution.width = 200
c.resolution.height = 300
var tmpC = c
tmpC.resolution.width = 120
/*
class is reference type
identical operator : === , !==
*/
print("class \(c.resolution.width) == \(tmpC.resolution.width). reference")
if c === tmpC {
print ("class identical operator. equal")
}
// else if c !== tmpC
As a general guideline, consider creating a structure when one or more of these conditions apply:
- The structure’s primary purpose is to encapsulate a few relatively simple data values.
- It is reasonable to expect that the encapsulated values will be copied rather than referenced when you assign or pass around an instance of that structure.
- Any properties stored by the structure are themselves value types, which would also be expected to be copied rather than referenced.
- The structure does not need to inherit properties or behavior from another existing type. Examples of good candidates for structures include:
- The size of a geometric shape, perhaps encapsulating a width property and a height property, both of type Double.
- A way to refer to ranges within a series, perhaps encapsulating a start property and a length property, both of type Int. - A point in a 3D coordinate system, perhaps encapsulating x, y and z properties, each of type Double.”
Swift Enumerations : Raw value, Initializing, indirect
// Enumerations : Raw value
enum ASCIICharacterControl: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
print("test\(ASCIICharacterControl.tab.rawValue)tabtab\(ASCIICharacterControl.lineFeed.rawValue)...")
enum Planet:Int {
case sun=1,mercury,earth,mars,neptune,jupiter
}
print("\(Planet.sun),\(Planet.earth.rawValue)..")
enum CompassPoint: String {
case east,west,south,north
}
print("\(CompassPoint.east)..\(CompassPoint.west.rawValue)")
// Enumerations : Initializing
var position = 3
if let planetTmp = Planet(rawValue: position) {
switch planetTmp {
case .earth:
print("you choose \(planetTmp)")
default:
print("you choose other except earth:\(planetTmp)")
}
} else {
print("there is no planet with rawValue:\(position)")
}
//Recursive Enumerations : indirect
indirect enum ArithmethicExpression {
case number(Int)
case addition( ArithmethicExpression, ArithmethicExpression )
case multiply( ArithmethicExpression, ArithmethicExpression )
}
let one = ArithmethicExpression.number(1)
let three = ArithmethicExpression.number(3)
let sum = ArithmethicExpression.addition(one,three)
let multi = ArithmethicExpression.multiply(sum,three)
func calculate(_ val: ArithmethicExpression ) -> Int {
var ret : Int = 0
switch val {
case .number( let n ):
ret = n
case let .addition( a, b ):
ret = calculate(a) + calculate(b)
case let .multiply ( a, b ):
ret = calculate(a) * calculate(b)
default:
print("nothing \(val)")
}
return ret
}
print( calculate(sum))
print( calculate(multi))
Swift Enumeration,Associated values
//1. Enumerations
enum SomeEnumeration {
}
enum CompassPoint {
case north
case south
case east
case west
}
enum Planet {
case Sun,Mercury,Earth,Mars,Jupiter,Neptune
}
var directionToHead = CompassPoint.north
print(directionToHead)
directionToHead = .west
print(directionToHead)
switch directionToHead {
case .north:
print("switch: \(directionToHead)")
case .south:
print("switch: \(directionToHead)")
case .east:
print("switch: \(directionToHead)")
case .west:
print("switch: \(directionToHead)")
}
//2. Associated Values
enum BarCode {
case upc(Int,Int,Int,Int)
case qrCode(String)
}
var bCode = BarCode.upc(1,3,4,66)
print(bCode)
bCode = .qrCode("hi hello")
print(bCode)
switch bCode {
case .upc(let leftPos,let topPos,let rightPos,let bottomPos):
print ("upc \(leftPos), \(topPos), \(rightPos), \(bottomPos)")
case let .qrCode(name):
print ("hey \(name)")
}
Swift autoclosure
// 1. Closure - Autoclosure
“An autoclosure is a closure that is automatically created to wrap an expression that’s being passed as an argument to a function. It doesn’t take any arguments, and when it’s called, it returns the value of the expression that’s wrapped inside of it. This syntactic convenience lets you omit braces around a function’s parameter by writing a normal expression instead of an explicit closure.”
“An autoclosure is a closure that is automatically created to wrap an expression that’s being passed as an argument to a function. It doesn’t take any arguments, and when it’s called, it returns the value of the expression that’s wrapped inside of it. This syntactic convenience lets you omit braces around a function’s parameter by writing a normal expression instead of an explicit closure.”
var customersInLine = ["james","kim","lee","richard","micheal","blondes","linda"]
let customerProvider = { customersInLine.remove(at:0) } // autoclosure : ()->String
print( customersInLine.count )
print( customerProvider() )
print( customersInLine.count )
//not autoclosure
func serve(customer: ()->String){
print("serve:\(customer())")
}
serve(customer: { customersInLine.remove(at:0) } )
print (customersInLine.count)
//autoclosure
func serveAutoclosure(customer: @autoclosure ()->String ){
print("serve by Autoclosure:\(customer())")
}
serveAutoclosure(customer: customersInLine.remove(at:0))
print (customersInLine.count)
// + escaping
var tempClosures : [()->String] = []
func collectClosures(itemClosure: @autoclosure @escaping ()->String){
tempClosures.append(itemClosure)
}
collectClosures(itemClosure: customersInLine.remove(at:0))
collectClosures(itemClosure: customersInLine.remove(at:0))
for i in tempClosures {
print("customer:\(i()), count:\(customersInLine.count)")
}
Swift closure : Capturing value, Escaping Closures
//1. Closure : Capturing value
func makeIncrement( forIncrement amount: Int) -> ()->Int {
var sum = 0 // this is captured value
func add () -> Int {
sum += amount
return sum
}
return add
}
let incrementBy5 = makeIncrement(forIncrement:5)
print(incrementBy5())
print(incrementBy5())
let incrementBy3 = makeIncrement(forIncrement:3)
print(incrementBy3())
print(incrementBy3())
//Closures are Reference Type
let incrementTemp = incrementBy3
print(incrementTemp())
//2. Closure : Escaping Closures
/*
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns.
*/
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
// closure is not called in this scope. @escaping required
// completionHandler() // closure is called in this scope. @escaping not required
}
func someFunctionWithNonescapingClosure(closure: () -> Void) {
closure()
}
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
someFunctionWithNonescapingClosure { x = 200 }
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
// Prints "200"
completionHandlers.first?()
print(instance.x)
// Prints "100”
Swift nested function, closure
// 1. nested function return type
func sumOrSub(enable:Bool) -> (Int,Int)->Int {
func add(_ a: Int, _ b:Int )->Int {
return a+b
}
func sub(_ a:Int , _ b:Int)->Int {
return a - b
}
if(enable){
return add
}
else {
return sub
}
}
print( sumOrSub(enable:true)(1,2))
// 2. closure
let names = ["james","charile","richard","hong","kim","lee"]
func backward(_ a:String, _ b:String)->Bool {
return (a > b )
}
var reversed = names.sorted(by:backward)
print (reversed)
reversed = names.sorted(by: { (a:String, b:String)->Bool in return a>b })
print (reversed)
reversed = names.sorted(by: { s1,s2 in return s1>s2 })
print( reversed)
reversed = names.sorted(by: { s1,s2 in s1>s2 })
print( reversed)
reversed = names.sorted(by: { return $0>$1})
print( reversed)
reversed = names.sorted(by: { $0>$1})
print( reversed)
reversed = names.sorted(by: > )
print( reversed)
//trailing closure
reversed = names.sorted(){ $0>$1}
print( reversed)
reversed = names.sorted{ $0>$1}
print( reversed)
reversed = names.sorted{ ( a, b) -> Bool in return a > b }
print( reversed)
Swift multiples return, variadic parameters, in-out parameters
// 1. multiples return values
func limitArray(array: [Int])->(min:Int, max:Int){
var tmpMin = 0,tmpMax = 0
for t in array {
if tmpMax < t {
tmpMax = t
}
if tmpMin > t {
tmpMin = t
}
}
return (tmpMin, tmpMax)
}
let limit = limitArray( array: [2,5,1,6,7,8,11])
print( limit.min, limit.max)
// 2. Variadic parameters
func average(_ vals: Int...)->Double {
var sum = 0
for val in vals {
sum += val
}
return Double(sum) / Double(vals.count )
}
print( average(1,2,3,4,5) )
// 3. In-Out parameters
func swapInt(_ a: inout Int, _ b: inout Int ){
let tmp = a
a = b
b = tmp
}
var a2 = 11
var b2 = 2
swapInt(&a2, &b2)
print(a2,b2)
Swift loop, guard
//2. label loop
let finalSquare = 25
var board = [Int](repeating: 0, count: finalSquare + 1)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var square = 0
var diceRoll = 0
gameLoop: while square != finalSquare {
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
switch square + diceRoll {
case finalSquare:
// diceRoll will move us to the final square, so the game is over
break gameLoop
case let newSquare where newSquare > finalSquare:
// diceRoll will move us beyond the final square, so roll again
continue gameLoop
default:
// this is a valid move, so find out its effect
square += diceRoll
square += board[square]
}
}
print("Game over!")
//3. guard
func greet(person: [String: String]) {
guard let name = person["name"] else {
return
}
print("Hello \(name)!")
}
greet(person: ["addr": "south korea, seoul"])
greet(person: ["name": "hjkim"])
// 4. checking API availability
if #available(iOS 10, macOS 10.12, *) {
// Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
// Fall back to earlier iOS and macOS APIs
}
피드 구독하기:
글 (Atom)