zzzwco


  • 首页

  • 分类

  • 标签

  • 归档

  • 关于

  • 搜索

Swift 命名空间(namespace)的实现

发表于 2020-03-25 | 分类于 ios
| 字数统计: 193
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/// 实例对象的包装器
public struct CCWrapper<WrappedType> {
/// 包装后的值
let wrappedValue: WrappedType
init(wrappedValue: WrappedType) {
self.wrappedValue = wrappedValue
}
}

/// 命名空间协议
public protocol NameSpaceWrapper {
associatedtype WrapperType
var cc: WrapperType { get }
static var cc: WrapperType.Type { get }
}

/// 命名空间协议默认实现
public extension NameSpaceWrapper {
var cc: CCWrapper<Self> {
return CCWrapper(wrappedValue: self)
}
static var cc: CCWrapper<Self>.Type {
return CCWrapper.self
}
}

// 使用
extension String: NameSpaceWrapper {}
extension CCWrapper where WrappedType == String {

var hi: String {
return "Hi, I'm \(self.wrappedValue)"
}

func sayHi(to person: String) {
print("\(self.wrappedValue) say hi to \(person)")
}

static func hi(_ person: String) {
print("Hi, \(person)")
}

}

print("Bruce".cc.hi)
//Hi, I'm Bruce

"Bruce".cc.sayHi(to: "Max")
//Bruce say hi to Max

String.cc.hi("Jack")
//Hi, Jack

Swift 关联类型(associatedtype)的使用

发表于 2020-03-24 | 分类于 ios
| 字数统计: 330

定义一个协议时,有时在协议定义里声明一个或多个关联类型是很有用的。关联类型给协议中用到的类型一个占位符名称。直到采纳协议时,才指定用于该关联类型的实际类型。关联类型通过 associatedtype 关键字指定。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protocol Eat {
associatedtype FoodType
func eat(_ food: FoodType) -> FoodType
}

protocol Food {
var weight: CGFloat { get set }
var desc: String { get set }
}

struct Meat: Food {
var weight: CGFloat
var desc: String
}

struct Vegetable: Food {
var weight: CGFloat
var desc: String
}

struct Person<T>: Eat {
func eat(_ food: Food) -> Food {
return food
}
}

我们定义了一个 Person,它每天都得吃饭,我们要求它遵循吃饭的协议 Eat,并实现了其中的 eat 方法。在协议 Eat 中我们声明了一个关联类型 FoodType。当 Person 的实例去调用 eat 方法时,我们使用泛型类型去指定之前的占位符 FoodType,那么我们就能清晰地知道 Person 的实例到底吃的是什么。

1
2
3
4
5
6
7
8
9
let p = Person<Food>()

let food1 = p.eat(Meat(weight: 1.2, desc: "meat"))
print("eat \(food1.desc), weight \(food1.weight)")
// eat meat, weight 1.2

let food2 = p.eat(Vegetable(weight: 0.8, desc: "meat"))
print("eat \(food2.desc), weight \(food2.weight)")
// eat meat, weight 0.8

Mac 终端配置:fish + omf

发表于 2019-12-13 | 分类于 mac
| 字数统计: 134

安装与配置 fish

根据官网:https://fishshell.com/ 指引安装即可。

安装完之后,使用命令sudo vim /etc/shells打开配置文件,在文末加上/usr/local/bin/fish,保存退出。

运行chsh -s /usr/local/bin/fish命令使fish成为默认 shell。

使用fish_config配置主题,这里我选Solarized Dark。

安装 oh my fish

curl -L https://get.oh-my.fish | fish

安装之后,使用omf install eclm主题即可。

其它

终端描述文件:

https://github.com/altercation/solarized

下载后导入名为 Solarized Dark ansi 的配置文件。

Git 查看某个文件的修改历史

发表于 2019-12-10 | 分类于 git
| 字数统计: 88

查看某文件的修改记录

git lg [filename]

查看某文件所有变更历史

git lg -p [filename]

查看某文件在某次提交中的变更历史

git show <commit-id> [filename]

恢复某个文件至某个版本

git checkout <commit-id> [filename]

lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

Cocoapods 1.8.4 CDN 无法使用的问题

发表于 2019-11-07 | 分类于 ios
| 字数统计: 268

好久没升级 Cocoapods 了,正好想升级一下,看到 官方文档 的视频演示,满心欢喜地去试用 CDN 。结果,心灰意冷了。

尝试了很多方法,仍然无法使用卖家秀一样的新特性。更可恨的是,我已经使用了 pod repo remove master 命令了。

经过几个小时的折腾后,放弃了。。。

看到 github 上有人提了同样的 issue ,给出的解决方案是不要使用 trunk,而是继续使用 master 库。希望这个 issue 能早日解决吧~

不得已,删除了 trunk (pod repo remove trunk),使用 镜像站点 重装了 cocoapods。

由于 Cocoapods 1.8.4 默认使用 CDN 来安装依赖,如果要用回原来的 master 库,需要指定 Podfile 的 source:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Uncomment the next line to define a global platform for your project
platform :ios, '12.0'

# source 'https://github.com/CocoaPods/Specs.git'
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

target 'test' do
# Comment the next line if you don't want to use dynamic frameworks
# pod 'ImagesView'
pod 'Kingfisher'
pod 'SnapKit'
use_frameworks!
# Pods for test

end

Socks5 to http

发表于 2019-02-16 | 分类于 trick
| 字数统计: 216

安装和配置

1
brew install porivoxy

安装后,编辑 /usr/local/etc/privoxy/config,搜索socks5找到下面这句:

1
#forward-socks5t	/		127.0.0.1:9050	.

在下面添加:

1
forward-socks5	/		127.0.0.1:port	.

port 为本机的 ss 代理的 socks5 端口。

配置文件中还有另外一句默认的:

1
listen-address 127.0.0.1:8118

这表示 privacy 只监听本机的 8118 端。

阅读全文 »

Go Modules

发表于 2019-02-15 | 分类于 go
| 字数统计: 490

简介

Go modules是随着 Go 1.11 发布的新型的包管理工具,这也是官方推荐的。有了go mod,项目将不再依赖于GOPATH,你可以在任何路径下创建和管理项目,但是下载的依赖包仍然会存储在$GOPATH/pkg/mod路径。

使用

配置

在 Mac 下,编辑~/.bash_profile文件,写入export Go111MODULE=on

初始化 Modules

在项目路径下,使用命令 go mod init <packagename>初始化

编辑 go.mod

初始化的 go.mod 会显示如下内容:

1
module packagename

添加依赖后:

1
2
3
4
5
6
module packagename

require (
github.com/test/A v1.2.3
github.com/test/B v1.2.3
)

如果你不知道要依赖的版本,可以使用 latest代替版本号,在安装依赖时,go 会自动安装最新的版本。

阅读全文 »

Go concurrency(并发)

发表于 2018-05-02 | 分类于 go
| 字数统计: 966

1. 简介

goroutine 是 Go 中的并发执行单位,可以理解为“线程”,但它不是“线程”。生成一个 goroutine 非常简单,只需 go 一下就实现了。在同一个程序中所有的 goroutine 共享一个地址空间。goroutine 通过通信来共享内存,而不是共享内存来通信。

channel 是各个 goroutine 之间通信的管道,它是引用类型,可以使用 == 进行比较,如果引用了相同的数据结构,则结果为真。传数据用 channel <- data,取数据用 <- channel。多数情况下,它是阻塞同步的。channel 可以设置为单向或双向,也可以设置缓存大小,在未被填满前不会发生阻塞。

select 可处理一个或多个 channel 的发送与接收,同时有多个可用的 channel 时按随机顺序处理。

阅读全文 »

Go reflection(反射)

发表于 2018-05-01 | 分类于 go
| 字数统计: 481

1. 反射的基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main

import (
"fmt"
"reflect"
)

type User struct {
Id int
Name string
Age int
}

func (u User) Hello() {
fmt.Println("Hello, world")
}

func Info(o interface{}) {
t := reflect.TypeOf(o)
fmt.Println("type:", t.Name())
// print "type: User"

if k := t.Kind(); k != reflect.Struct {
fmt.Println("类型错误")
return
}

v := reflect.ValueOf(o)
fmt.Println("fields:")

for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
val := v.Field(i).Interface()
fmt.Printf("%6s: %v = %v\n", f.Name, f.Type, val)
}
// print
// fields:
// Id: int = 1
// Name: string = ok
// Age: int = 12

for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
fmt.Printf("%6s: %v\n", m.Name, m.Type)
}
// print "Hello: func(main.User)"
}

func main() {
u := User{1, "ok", 12}
Info(u)
}

注意:User 中的属性必须为大写程序才能正常运行,Go 是根据属性的首字母大小写来确定访问权限的,大写表示公有,小写表示私有。同理,方法签名 Hello 为小写,一样无法反射出对应的方法名。

阅读全文 »

Go interface(接口)

发表于 2018-04-28 | 分类于 go
| 字数统计: 402

1. 概念

接口是一个或多个方法签名的集合,只有方法声明,没有实现。

只要某个类型拥有该接口的所有方法签名,即算实现了该接口,无需显式声明了哪个接口,这称为 Structural Typing 。

接口也是一种类型,它是一种抽象类型,空接口 interface {} 类似于 NSObject 这样的万物之主,虽然 Go 中是没有 class 的概念,但 interface 实现了继承多态的效果。

2. 使用

阅读全文 »
1234…6
zzzwco

zzzwco

52 日志
11 分类
52 标签
GitHub Weibo Twitter
Creative Commons
© 2017 — 2022 zzzwco
本页点击 次   |  本站总点击 次   |  您是第 位访客   |  
博客全站共44.3k字
0%