title: “Why coding like This —— Optional 揭秘”
date: 2015-08-12 00:21:16
categories: “why coding like this”
tags: [swift进阶]

Optional 揭秘

Topic 1:

请简单写出可选类型的声明方式,以及几种解包形式。

Example:

/// 几种声明方式
var optionalValue : Optional<Int> //完整声明 注意<>中的都是类型
var optionalValue2 : Int?         //显示声明
var optionalValue3 : Int!         //隐式声明

/// 几种解包
/// 演示值
var someOptional:Int? = 3  //初始值为3

/// 1.通过判断是否等于nil 这里并未解包 只能保证安全性
if someOptional != nil{
  println("value is \(someOptional!)")
}

/// 2.if-let绑定
if let value = someOptional{
  println("value is \(value)")
}
/// 3.??解包
println("value is \(someOptional ?? 2)")

/// 4.swift2.0新的匹配模式 但是要在xcode7环境

//新增使用enumeration匹配 也就是枚举匹配方式
if case .some(let x) = someOptional{
println("someOptional value is \(x)") //如果为nil 情况 可不会输出东西 因为匹配的是Some!
}

//新增使用可选模式匹配

if case let x? = someOptional{
println("someOptional value is \(x)") //不需要对x进行解包之类的东东
}

其中第四种方法仅在xcode7环境 以及swift2.0语法下支持。更多语法改动请点击这里。关于可选类型解包请点击这里。 更多基础语法请查看官方文档。

why coding like this?

命题一

给定某个变量,在程序运行的时候存在两种情况:不存在任何值;存在值,等于x。设计一个类型来封装这种情况。

思路

其实谈不上思路,但是命题中指出存在两种情况,让我不禁想到枚举(当然更多受swift本身影响),swift中的枚举无比强大,倘若你是新手,建议再次阅读官方文档enumerate章节。Ok,接下来就是代码部分开始设计枚举类型。

代码

声明:一步步来,你会发现很有意思。

enum MyOptional{
  case None
  case Some
}

根据思路我们写出了该枚举类型,None表示不存在值,Some表示有值;不难发现定义的类型存在一些弊端,首先我们的变量可能是Int,String,Double,而此处未明确涵盖;其次在有值情况下并未和实际值关联。根据以上几点对自定义枚举进行修改,如下:

enum MyOptional<T>{
  case None
  case Some(T)
}
//特别申明 这种方式在swift1.2下是不支持的 由于和本节无关 就不扯了 但是我们自定义一个类来包裹
//貌似swift2.0是支持的....
enum Result<T>{
  case Success(T)
  case Failure(NSError)
}

我们巧妙使用了泛型匹配任何类型,并且利用枚举的Associated Values对存在值x进行了关联。为了更好地使用我们会加上初始化方法声明,代码如下:

enum MyOptional<T>{
  case None
  case Some(T)
  //生成一个有值的可选类型
  init(_ value:T){
    self = .Some(value)
  }

  //nil
  init(_ nilLiteral:()){
    self = .None
  }

}
//my optional value
var myValue : MyOptional<Int> = MyOptional(2)
var myNil: MyOptional<Int> = MyOptional()
//测试下我们的蹩脚可选类型
switch myValue{
case .None:
  println("nil")
case .Some(let x):
  println("value is \(x)")
}
switch myNil{
case .None:
  println("nil")
case .Some(let x):
  println("value is \(x)")
}

看上去还不错,但和swift中的可选类型有一定差距,以上仅仅只是让你从另一面去了解可选类型。

命题二

可选类型中的??解包运算符你能否自己实现? 自定义一个-->解包运算符!

思路

解包行为无非是那么几种,我们只要重载运算符即可。

代码

infix operator -->{ associativity right precedence 110 } 

func --><T>(optional:T?,defaultValue:T)->T{
  // 我选择了if-let解包
  if let x = optional{
    return x
  }else{
    return defaultValue
  }
}
//测试下
var oo : Int? = nil

let r = oo --> 5    //输出5

首先我们仍然使用泛型来声明,那么传入一个可选类型optional,它可能有值=x,可能不存在值(nil),无值的情况下使用defaultValue

但是考虑到defaultValue有时候并非是一个值,也许是一个闭包呢,反馈一个T值。因此对函数稍加修改。

//代码二
func --><T>(optional:T?,defaultValue:()->T)->T{
  // 我选择了if-let解包
  if let x = optional{
    return x
  }else{
    return defaultValue()
  }
}
var rr = oo --> {7}  //返回7

可以看到使用过程中我们对defaultValue闭包必须明确表示,用{}来包裹。可是单值情况下,用{}包裹感觉很变扭,因此我们还需要稍加改动,利用autoclosure特性来解决这一问题,最后代码如下:

infix operator -->{ associativity right precedence 110 }    //这个很重要
func --><T>(optional:T?,@autoclosure defaultValue:()->T)->T{
  // 我选择了if-let解包
  if let x = optional{
    return x
  }else{
    return defaultValue()
  }
}

var rrr = oo --> 5+4        //可以看到 自动把 5+4 当做一个闭包来干了

总结:可选类型难度不大,但是对初学者来说还是一道坎,毕竟以前没有这种概念,多码码代码自然就熟悉了。不知不觉写到深夜了,洗洗睡了。

Why Coding Like this -------Optional揭秘 自己写一个可选类型类的更多相关文章

  1. 【Coding 技术博文】在 Swift 项目中实现侧滑菜单-利用 SWRevealViewController

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  2. Why Coding Like this -------map函数揭秘

    首先声明一个函数名位handleClosure的函数,主要作用是对传入的x元素进行2*x+1的线性变换,最后将处理后的结果值返回。现在来调用handleIntArray函数,首先传入intArray数组,接着将handleClosure函数作为一个参数传入,那么在什么时候调用呢?仔细分析两个handle函数,它们看起来非常相似,唯一的区别就是在传入参数上。感谢Swift提供了generics为我们很好的解决了这一难题。下次带来whycodinglikethis---filter的实现

  3. Why Coding Like this -------Filter函数揭秘

    通过Map章节学习后,立马意识到该函数的局限性—————仅适用筛选后缀是.swift的文件。whycodinglikethis系列,更多是用Why,How看待代码,摒弃那种我只要会写,至于为什么?下文带来reduce的揭秘。

  4. Why Coding Like this -------Reduce揭秘

    代码:可以看到对于sum函数传入Int类型数组,首先我们声明一个Int类型变量用于保存最后的求和结果值,初始值为0;接着使用for-in语句遍历传入的数组,使用result+=x逐一求和累加;最后返回结果值result。当然有一点切记不要遗忘,就是初始值result=1。","say","by","optionalswift"],最后整合成“HelloWorld!saybyoptionalswift”。

  5. Why Coding Like this -------Optional揭秘 自己写一个可选类型类

    Example:其中第四种方法仅在xcode7环境以及swift2.0语法下支持。关于可选类型解包请点击这里。但是考虑到defaultValue有时候并非是一个值,也许是一个闭包呢,反馈一个T值。可以看到使用过程中我们对defaultValue闭包必须明确表示,用{}来包裹。可是单值情况下,用{}包裹感觉很变扭,因此我们还需要稍加改动,利用autoclosure特性来解决这一问题,最后代码如下:总结:可选类型难度不大,但是对初学者来说还是一道坎,毕竟以前没有这种概念,多码码代码自然就熟悉了。

  6. Swift编程规范之 Coding Style

    这里需要注意的是,对于某些应该被声明为private的变量因为测试用途而声明为了internal,那么应该在注释里特别地注明。Theonlytimeyoushouldbeusingimplicitlyunwrappedoptionalsiswiths.Ineveryothercase,itisbettertouseanon-optionalorregularoptionalvariable.Yes,therearecasesinwhichyoucanprobably“guarantee”thattheva

  7. centos 安装 matplotlib

    解决方案有如下三种:一、在文件头部添加如下注释码:#coding=例如,可添加#coding=utf-8二、在文件头部添加如下两行注释码:#!

  8. ubuntu下ssh密钥到github(或者coding)

    1.为Git创建全局name和全局email:2.打开terminal,判断是否有ssh软件(步骤略);3.用ssh-keygen命令在个人文件夹下生成公钥密钥:4.进入~/.ssh文件夹:5.把密钥文件加入ssh中:5(branch).如果生成key加不到ssh中,ssh-addid_rsa命令报错Couldnotopenaconnectiontoyourauthenticationagent,

  9. 正则表达式续

    pageNum=3http://www.jikexueyuan.com/course/android/?pageNum=4http://www.jikexueyuan.com/course/android/?

  10. Ubuntu 安装git和配置ssh(Coding实例)

    安装git步骤1步骤2其实也就是这里两步就可以安装好了,当然最后验证就是git-v查看版本了。配置ssh由于我的git代码仓库,我选择的是Coding,这里就用它来做详细说明,差异就是怎么使用最后生成的ssh了。查看是否有ssh密匙如果没有会有下面的提示:-bash:cd:/root/.ssh:Nosuchfileordirectory生成密匙这里我的是:ssh-keygen-trsa-C"zhuming3834@sina.com"。这里建议设置成和自己的git账号的邮箱一致。这里密匙ssh就生成好了,在

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部