分类 Mac 下的文章

Golang中的接口

软硬件环境

  • Windows 10
  • Go 1.8

什么是接口?

接口定义了一组方法,但是这些方法不包含实现的代码,另外接口里也不能包含变量。如下定义了一个接口

type intfNamer interface {
    Method1(param_list) return_type
    Method2(param_list) return_type
    ...
}

为什么要设计接口?

Go不是传统意义上的面向对象编程语言,它没有类及其继承的概念。接口是一种契约,实现类型必须满足它,它描述了类型的行为,规定类型可以做什么。接口彻底将类型能做什么,以及如何做分离开来,使得相同接口的变量在不同的时刻表现出不同的行为,这就是多态的本质。

简单接口示例

package main

import (
    "fmt"
)

type namer interface {
    area() int
}

type rect struct {
    width,height int
}

type square struct {
    side int
}

func (r rect) area() int {
    return r.height * r.width
}

func (s square) area() int {
    return s.side * s.side
}

func main() {
    var a = rect{4,3}
    var b  = square{6}

    fmt.Println(a.area())
    fmt.Println(b.area())
}

程序执行结果为

mtqq_mosquitto

测试某个值是否实现了某个接口?

type Stringer interface {
    String() string
}

if sv, ok := v.(Stringer); ok {
    fmt.Printf("v implements String(): %s\n", sv.String()) // note: sv, not v
}

接口嵌套

一个接口可以包含一个或者多个其它的接口,如下

type ReadWrite interface {
    Read(b Buffer) bool
    Write(b Buffer) bool
}

type Lock interface {
    Lock()
    Unlock()
}

type File interface {
    ReadWrite
    Lock
    Close()
}

File接口包含了ReadWrite接口、Lock接口和方法Close,任何实现了File接口的类型同时也实现了接口ReadWrite和Lock

需要注意的点

  • 类型不需要显式地声明它实现了某个接口,接口被隐式地实现,多个类型可以实现同一个接口
  • 一个类型可以实现多个接口
  • 实现了某个接口的类型,可以有其它的方法

接口方法中类型T和T*的区别

type typeA struct {

}

type intfA interface {
    func1()
}

func (a *typeA) func1() {

}

func func2(i intfA)  {
    i.func1()
}

var a typeA

上面的例子中,在a上调用func2时,会导致一个编译器错误,因为func2需要一个intfA,而它的方法func1之定义在指针上。

Go 语言规范定义了接口方法集的调用规则:

  • 类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
  • 类型 T 的可调用方法集包含接受者为 T 的所有方法
  • 类型 T 的可调用方法集不包含接受者为 *T 的方法

小结

综上所述,接口就是一组方法的集合。 只要一个类型实现了某个接口中的方法,那么,这个接口类型的变量就可以接受这个类型的变量,而且同一个接口,可以接收不同类型的变量。

MacOS下配置Go开发环境

软硬件环境

  • macOS Sierra
  • go 1.8

go语言简介

Go是Google开发的一种编译型、并发型、具有垃圾回收功能的编程语言,出自三位大牛罗伯特·格瑞史莫(Robert Griesemer)、罗勃·派克(Rob Pike)及肯·汤普逊(Ken Tompson)之手,于2009年11月正式推出。Go天生的支持并发,所以非常适合服务器端软件的开发,尤其是云计算领域。

安装go

下载go安装包https://golang.org/dl/,这里选择目前最新版本1.8,接着进行傻瓜式安装。

一点配置

export GOPATH=/Users/djstava/Workshop/go
export GOBIN=/Users/djstava/Workshop/go/bin
export PATH=$PATH:$GOBIN

为方便起见,将上述配置语句写进~/.bash_profile,然后执行

source ~/.bash_profile

设置完后,检查下是否配置成功,在terminal中输入go env

GOARCH="amd64"
GOBIN="/Users/djstava/Workshop/go/bin"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/djstava/Workshop/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/1p/w8h4jd_94c5d9pvc0r2660wr0000gn/T/go-build205680752=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

这里需要说明一下,$GOPATH指定的是go工程目录,$GOBIN是go程序生成的可执行文件的路径

go工程目录结构

在$GOPATH目录中一般有3个子目录,分别是

  • src 存放源代码
  • bin 编译后生成的可执行文件,上面配置中已经将该目录放到$GOBIN中了
  • pkg 编译后生成的文件,比如.a文件

第一个go程序

环境配好了,照例写一个hello world程序吧

cd $GOPATH
mkdir src bin pkg
cd src
mkdir hello
cd hello
vi main.go

这里用vi编辑器进行编辑,在main.go文件中敲入如下代码

package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world!")
}

编写完毕后,直接在hello文件夹下编译安装

go install

生成的可执行文件hello,存放在$GOPATH/bin下

代码解析

这里的package跟java里的类似,main代表的是可执行应用,如果是其它的话表明这是个应用包。import语句是导入包的意思,fmt是系统内建的,Println是fmt中的函数,这个很容易理解。

常见的IDE

一直非常喜欢jetbrains的全家桶,但是他们家的go IDE Gogland还没有发布正式版,测试版勉强可以用,下载地址https://www.jetbrains.com/go/?fromMenu。

除此之外,大部分都是文本编辑器+go插件的组合,在github上找到一个列表组合,可以去看看,地址是https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/01.4.md

参考资料

https://golang.org/doc/

iOS自学笔记之plist文件

软硬件环境

  • macOS Sierra
  • Xcode 7.0.1

plist文件简介

iOS开发中经常会使用到plist文件,那么plist文件到底什么呢?plist的全称是Property List即属性列表文件。本质上它是一个XML文件。做过Android开发的童鞋肯定知道SharedPreference,plist就是iOS开发中的SharedPreference。plist文件一般用于存储用户设置的信息,其存储的信息量不宜过大,大数据量可以使用数据库,这个后面会学习到。

plist文件的读写操作

回到Xcode开发环境,我们创建一个iOS工程iOSPlistOpsDemo来具体操作plist文件,工程创建完毕,打开工程默认的info.plist文件来看看它到底长什么样子?

plist_01

如果你习惯了以代码的形式查看,可以右击info.plist —> Open As —> Source Code打开查看

plist_01

工程info.plist已经包含了一些iOS默认工程的设置,我们暂不使用它。这里新建一个plist文件djstava.plist,File —> New —> File —> iOS —> Property List,然后增加如下几条数据对

plist_01

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"djstava" ofType:@"plist"];
    NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
    NSLog(@"%@",data);
}

编译后启动模拟器,会看到如下运行结果

plist_01

数据读取成功后,我们再来看看怎么讲数据写入到plist文件中

    [data setObject:@"Shanghai" forKey:@"location"];
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    NSString *fileName = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"djstava.plist"];
    
    NSLog(@"%@",fileName);
    
    [data writeToFile:fileName atomically:YES];

再次编译运行程序,按照打印出来的路径,找到对应的djstava.plist文件,打开查看是不是已经有数据了,如下图所示

plist_01

这里需要注意一点的是工程中的djstava.plist并没有改变。如果你嫌这样查看不方便,可以在数据写入后再将它读出来进行比较。

Info.plist文件的读写

Info.plist是工程的配置文件,在每个xcode工程创建时会自动生成一个,它保存这该工程的基本配置信息,你可以增加/删除配置项。Info.plist的信息读取和上面的实例基本类似

    //Info.plist
    //获取文件的全路径
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
    
    //解析 Info.plist
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath];
    
    //获取当前的版本号
    NSString *version = dict[@"CFBundleShortVersionString"];
    NSLog(@"%@",version);
    
    //获取storyboard文件
    NSString *storyFile = dict[@"UIMainStoryboardFile"];
    NSLog(@"%@",storyFile);

plist_01

源码下载

https://github.com/djstava/iOSLearning/tree/master/iOSPlistOpsDemo

iOS自学笔记之XIB的使用

软硬件环境

  • macOS Sierra
  • Xcode 8.2.1

前言

前面学习iOS编程时,画UI控件的时候用的都是直接敲代码的方式,基本都是先创建一个相应控件的对象,然后设置对象属性,最后添加相应的事件响应方法。那强大如Apple这样的公司有没有提供一种更方便、更易学的UI编写方法呢?答案是肯定的。那就是今天本文的主角XIB。它是一种可视化的方法,极大地降低了学习iOS编程的门槛。

XIB实践

创建一个名叫iOSXIBDemo的工程,打开工程info.plist文件,将Main storyboard file base name这个标签去掉,如下图所示

iOS_xib_01

创建一个iOS的Cocoa Touch类RootViewController,作为根视图控制器,它继承自UIViewController,并勾选上"Also create XIB file"选项

iOS_xib_02

iOS_xib_03

打开RootViewController.xib文件,从控件区中拖动一个UILabel和一个UIButton,界面上的操作就是这么简单,那XIB怎么跟代码同步呢?别着急,找到Xcode右上角的双环标记,单击它

iOS_xib_05

iOS_xib_06

这样在同一个画面就能同时看到XIB和RootViewController.m了,接着开始进行代码同步。找到XIB中的UILable对象,同时按住Ctrl键 + 鼠标左键,将光标移动到RootViewController.m中的@interface和@end之间放开,弹出对话框。这里Connection的类型,对于UILabel来说是选Outlet,而UIButton选的是Action。我的理解是的可以响应事件的控件就选Action

iOS_xib_07

iOS_xib_08

绑定完成后,在对应的代码前会有个实心圆。在UIButton点击响应时间函数加句打印

- (IBAction)mButton:(id)sender {
    NSLog(@"button clicked.") ;
}

接下来开始加载根视图控制器,修改AppDelegate.m中的didFinishLaunchingWithOptions方法,同时需要将RootViewController.h头文件import进来

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds] ;
    
    RootViewController* root = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:[NSBundle mainBundle]] ;
    
    self.window.rootViewController = root;
    
    [self.window makeKeyAndVisible] ;
    
    return YES;
}

最后代码执行的效果如下

iOS_xib_09

源码下载

https://github.com/djstava/iOSLearning/tree/master/iOSXIBDemo

iOS自学笔记之UISwitch和UITextField

软硬件环境

  • macOS Sierra
  • Xcode 7.0.1

UISwitch

UISwitch是一个状态转换的控件,包括打开和关闭2种状态,不同的状态相应地实现不同的业务逻辑。

- (void)viewDidLoad {
    [super viewDidLoad] ;
    // Do any additional setup after loading the view, typically from a nib.
    
    //创建一个UISwitch对象
    UISwitch* mySwitch = [[UISwitch alloc] init] ;
    
    //设置UISwitch的位置,注意,UISwitch的宽和高是无法改变的
    mySwitch.frame = CGRectMake(100, 100, 100, 40) ;
    
    //UI上那个点的颜色
    mySwitch.thumbTintColor = [UIColor redColor] ;
    
    //打开状态的颜色
    mySwitch.onTintColor = [UIColor blueColor] ;
    
    //UISwitch的初始状态
    //YES : 打开状态
    //NO : 关闭状态
    //mySwitch.on = YES ;
    
    //或者可以使用方法来设置,使用动画效果
    [mySwitch setOn:YES animated:YES] ;
    
    //响应事件
    [mySwitch addTarget:self action:@selector(switchPress) forControlEvents:UIControlEventValueChanged] ;
    
    [self.view addSubview:mySwitch] ;
 }

//UISwitch事件响应方法
- (void)switchPress {
    NSLog(@"switch is pressed.") ;
}

代码执行效果如下

uiswitch_01

UITextField

UITextField是一个可以输入文本的控件,类似于android中的Editline。

    //创建UITextField对象
    UITextField* textField = [[UITextField alloc] init] ;
    
    //设置位置
    textField.frame = CGRectMake(100, 300, 200, 40) ;
    
    //显示的文本
    textField.text = @"哈啰" ;
    
    //设置字体及大小
    textField.font = [UIFont systemFontOfSize:20] ;
    
    //设置文本的颜色
    textField.textColor = [UIColor blackColor] ;
    
    //提示文字,当textField.text为空时显示
    textField.placeholder = @"请输入文本..." ;
    
    //是否作为密码
    //YES : 显示圆点加密
    textField.secureTextEntry = NO ;
    
    //边框style
    textField.borderStyle = UITextBorderStyleRoundedRect ;
    
    //keyboard类型
    textField.keyboardType = UIKeyboardTypePhonePad ;
    
    [self.view addSubview:textField] ;

uitextfield_01

源码下载

https://github.com/djstava/iOSLearning/tree/master/iOSUISwitchAndUITextField