swift 学习(一)基础知识 (基本数据类型,操作符,流控制,集合)
xcode 中调用API帮助
1、查看简单信息,选中后 按键 control +左键单击 或者按 右侧属性栏 里的帮助按钮
2、完整API,选中后 按键 control +左键双击
3、查看类、函数等的注释,参数列表等,alt +左键单击
4、代码块注释与取消注释的快捷键 都是 command + /
5、---不能用try...catch,但可用assertion 调试,有多个重载版本,assert(useDate<=0,"不符合则报错")
swift2.0中已引入do-catch语句
正文
初步印象
1. 字符统一用unicode编码,区分大小写,有很多类似js,java的用法
2. 类型安全:有可选类型,可选类型的值缺失时为 nil ,不再需要对一个值判别是否为Null,变量声明时已经确定
3. 在swift中,数字字面量之间的运算,支持隐式类型转换,但数字类型的变量和常量之间的运算,则不再支持隐式类型转换。
4. 标示符命名规则与C相同,但是 关键字可以做标示符
let π = 3.14 等价于 let `π` = 3.14
var `class`="sdd"
5. 字符串比对时加入了更多判断。不再只是简单地比对组成字符串的标量,而是会比对最终表现形式
6. 字符和字符串都用双引号
7. 句末不用写分号,但多条语句写在同一行时要加
8. 变量声明用var, 常量用let,因此变量声明格式 变化较大 ,数据类型编译器会自动识别,一般不用显式声明
let a = 2
var b: Double = 4
var aInt = 4, bInt = 7
var p1 = 10,p2:Double
9. swift 语法内容很少,使用也很方便。而且函数是第一性的,也有全局变量,面向对象,面向过程,函数式都可以尝试。就是太多与objective-c相关的东西。
10. 声明字典,数组用 方括号,而不是花括号, 元组 用圆括号
11. 接口关键字改做protocal,更形象了
12. 枚举和结构的功能增强了,可以加入属性,方法,也可以实现接口
一段Swift代码(可选类型的源码)
enum Optional<T> : Reflectable, NilLiteralConvertible {
case None
case Some(T) /// Construct a `nil` instance.
init() /// Construct a non-\ `nil` instance that stores `some`.
init(_ some: T) /// If `self == nil`, returns `nil`. Otherwise, returns `f(self!)`.
func map<U>(f: @noescape (T) -> U) -> U? /// Returns `f(self)!` iff `self` and `f(self)` are not nil.
func flatMap<U>(f: @noescape (T) -> U?) -> U? /// Returns a mirror that reflects `self`.
func getMirror() -> MirrorType /// Create an instance initialized with `nil`.
init(nilLiteral: ())
} extension Optional : DebugPrintable { /// A textual representation of `self`, suitable for debugging.
var debugDescription: String { get }
}
注意点
1、 xcode 中 swift 运算符 两边要加空格,否则多数时候会报错(赋值 和 比较)
关键字 共60个
与声明有关的14个:class, deinit, enum, extension, func, import, init, let, protocol, static, struct, subscript, typealias, var
与语句有关的14个:break, case, continue, default, do, else, fallthrough, if, in, for, return, switch, where, while
表达式和类型关键字12个:as, dynamicType, is, new, super, self, Self, Type, _COLUMU_ , _FILE_ , _FUNCTION_ , _LINE_
特定上下文中使用的20个:associativity, didset, get, infix, inout, left, mutating, none, nonmutating, operator, override, postfix, precedence, prefix, rightset, unowned, unowned(safe), unowned(unsafe), weak, willset
补充:finaly private public internal dynamic
@IBoutlet @IBAction @UIApplicationMain @objc
@autoclosure @autoclosure(escaping)
@autoclosure:用在函数的里标记一个参数,然后这个参数会先被隐式的包装为一个closure,再把closure作为参数给这个函数。 从而实现对传递给这个参数的表达式延迟求值。
func myassert(@auto_closure predicate : () -> Bool) {
#if !NDEBUG
if predicate() {
abort()
}
#endif
} //调用
myassert(someExpensiveComputation() != 42)
func &&(lhs: LogicValue, @auto_closure rhs: () -> LogicValue) -> Bool {
return lhs.getLogicValue() ? rhs().getLogicValue() : false
}
1.2 新增:@noescape:可以用在函数的闭包参数上,这意味着这个参数是唯一可被调用的(或者用在函数调用时以参数的方式出现),其意思是它的生命周期比函数调用的周期短,这有助于一些小小的性能优化,但最重要的是它屏蔽了闭包中对self.的需求。这使得函数的控制流比其他更加透明。在未来的beta版本中,标准库函数将普遍采用这种特性,比如autoreleasepool():
func autoreleasepool(@noescape code: () -> ()) {
pushAutoreleasePool()
code()
popAutoreleasePool()
}
使用在函数参数上的 @autoclosure属性现在含有@noescape新属性的功能,这个改进限制了@autoclosure作为控制流程以及惰性计算的能力。
第二种形式。@autoclosure(escaping), 和@autoclosure有着同样的调用形式,但是它允许产生结果的闭包在实现中缓存
运算符
优先级排序:
最高: ++, --, !, ~, - , +
160: << , >>
150: * , / , % , & , &* , &/ , &%
140: + , - , &+ , &- , | , ^
135: ..< , ...
132: is , as
130: < , <= , > , >= , == , != , === , !==
120: &&
110: ||,??
100: ?:
90: =, *=, /=, %=, +=, -=, <<=, >>=, &=, |=, ^=, &&=, ||=
swift特点
swift 赋值运算符并不能将自身作为一个值进行返回
if x = y {} // 报错
println(a = 3) // ()
swift 默认情况下算数运算符不容许值溢出,需使用溢出运算符
&+,&*: 溢出加法 用于整数 上溢出
var max = UInt16.max // 65535
println(max + 1) // 报错
println(max &+ 1) // 0
var max = Int16.max // 32767
println(max &+ 1) // -32768
&-,&*: 整数下溢出
&/, &% 解决除数为0 的情况,xcode不识别了,已经被移除
swift中可以浮点数求余
let a = 3.667 % 1.3 // 1.067
swift 中提供了 恒等运算符===,!==,用来测试两个对象的引用是否来自同一个对象实例
可选类型与拆封运算
// nil不同于c中的NULL,它表示值缺失,而不是空指针
// 只有可选类型的变量或常量才可接受nil,非可选类型的变量或常量不能接受nil
func divide(a:Double,b:Double) ->Double? {
if(b == 0){
return nil
}
return a / b
} let result1 : Double? = divide(100,1)
println(result1) // Optional(100.0)
//强制拆封 (确定可选类型一定有值,可在读取它时通过拆封获取这个值)
if result1 != nil{
println(result1!) //100
result1?.hashValue
} //隐式拆封(更方便访问,会自动解封,若此时数据为nil,则后续操作可能出错)
let result2 : Double! = divide (100,0)
println(result2) //nil
// result2.hashValue // 报错
result2?.hashValue // nil,添加问号则如果result2为nil就不会执行后续
let result3 : Double! = divide (100,2)
println(result3) //50.0
result3.hashValue
?? 空值合并运算符
// 对 a 进行判断,如果不为 nil 则解包,否则就返回 b
// a 必须是 optional 的
// b 必须和 a 类型一致
// 相当于三目运算符的简化版
var a: String? = "a"
var b: String? = "b"
var c = a ?? b // "a" a = nil
c = a ?? b // "b"
b = nil
c = a ?? b ?? "c" // "c" //简化代码
if allowEmpty || items?.count ?? 0 > 0 {
}
区间运算符分为闭区间 (...) 和左闭右开区间 (..<)
//1...100 等同于 1..<101,区间
// 区间运算符其实返回的是一个 Range<T> 对象,是一个连续无关联序列索引的集合。 // .....
let aNumber:Int = 3
switch aNumber
{
case 0...5:
println("This number is between 0 and 5")
case 6...10:
println("This number is between 6 and 10")
default:
println("This number is not between 0 and 10")
} // .....
(1...10).map{
"$\($0)" + ".00"
} // .generate() 遍历 Range<T> 中的值。
var range = 1...4
var generator = range.generate() // {startIndex 1, endIndex 5} var item:Int?
do{
item = generator.next()
println(item)
}while(item != nil) //区间运算符返回的是一个 ClosedInterval 或者 HalfOpenInterval 的东西,
//类型只要是 Comparable 就可以了。所以我们也可以把 String 放到 ... 里。 let interval3 = 4.6...7.8
interval3.contains(4.88) // true //通过 String 的 ClosedInterval 来输出字符串中的小写字母:
let test = "Hello"
let interval = "a"..."z"
// 交集
let interval2 = interval.clamp("d"..."h") for c in test.characters {
if interval.contains(String(c)) {
println("\(c)")
}
} //e l l o
+Inf, -Inf, NAN
//let a = 23 / 0 // 报错,0不能做除数 let b = 23.0 / 0 // inf 正无穷大
let bb = 23.0 / -0 // inf 正无穷大
let c = -23.0 / 0 // -inf 负无穷大
let cc = -23.0 / -0 // -inf 负无穷大
let d = 0.0 / 0 // nan 非数
let dd = 0.0 / -0 // nan 非数 b == bb // true
c == cc // true
d == dd // false
运算符重载
1. 非常实用,但也相当有风险,可读性问题,可使用字符为:/ = – + * % < > ! & | ^ . ~
2. 运算符函数即便写在类内部,定义后也会自动进入全局Global作用域,而不是作为类的一个成员函数
struct Vector2D {
var x = 1.0, y = 1.0
} // 实现结构类型Vector2D的加法
func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
func *(vector2D: Vector2D,scalar:Double)->Vector2D{
return Vector2D(x: vector2D.x * scalar, y: vector2D.y * scalar)
}
// 1.实现 组合赋值运算符 左参数要设置为inout,赋值运算没有返回值
func += (inout left: Vector2D, right: Vector2D){
left = left + right
}
// 3. 会把1,2都覆盖了,不会报错
func += (left: Vector2D, right: Vector2D)->Vector2D{
let left2 = left + right
return left2
}
// 2.也可以有返回值,与1 不能并存
func += (inout left: Vector2D, right: Vector2D)->Vector2D{
left = left + right
return left
} // 实现一个单目运算符,需要加前缀prefix或 postfix
//
prefix func -(vector2D:Vector2D)->Vector2D{
return Vector2D(x: -vector2D.x, y: -vector2D.y)
} // 1.运算结果要保存,则要用inout
prefix func ++(inout vector2D:Vector2D)->Vector2D{
vector2D = vector2D + Vector2D(x: 1,y: 1)
return vector2D
}
// 3.会覆盖1,2 。不保存运算结果,有返回值
prefix func ++(vector2D:Vector2D)->Vector2D{
let vector2D2 = vector2D + Vector2D(x: 1,y: 1)
return vector2D2
}
// 2. 没有返回值
prefix func ++(inout vector2D:Vector2D){
vector2D = vector2D + Vector2D(x: 1,y: 1)
} postfix func ++(inout vector2D:Vector2D)->Vector2D{
let _vector2D = vector2D
vector2D = vector2D + Vector2D(x: 1,y: 1)
return _vector2D
} // 非是对原有操作符的新应用,则要先声明其为操作符
prefix operator +++ {}
prefix func +++(var c: Vector2D) -> Vector2D{
c += c
c += Vector2D(x: 1.0, y: 1.0)
return c
}
/// 自定义运算符需要遵循两段式,即需要先声明运算符
/// infix / prefix / postfix
/// associativity 表示结合性:left,rigth,none,默认为none
/// 指的事和其他运算符优先级相同的情况下,是从左边开始计算还是右边
/// precedence 表示优先级的数值,0...255,默认100
/// assignment 定义组合运算符时需要用到这个,
infix operator +-{ associativity left precedence 140}
func +-(left:Vector2D,right:Vector2D)->Vector2D{
return Vector2D(x:left.x + right.x,y:left.y - right.y)
} infix operator +-={associativity right precedence 140 assignment}
func +-=(inout left:Vector2D,right:Vector2D)->Vector2D{
left = Vector2D(x:left.x + right.x,y:left.y - right.y)
return left
} var point = Vector2D(x: 3.0, y: 1.0)
var v1 = Vector2D(x: 1,y: 1)
++v1 //{x 2, y 2}
v1 //{x 2, y 2}
v1++ //{x 2, y 2}
v1 //{x 3, y 3}
-v1 //{x -3, y -3}
+++point //{x 7.0, y 3.0}
point //{x 3, y 1} v1+-point //{x 6, y 2}
v1+-=point //{x 6, y 2}
v1 //{x 6, y 2}
let v3 = v1 += point
v3
v1
数据类型
swift中,不同于c,java等的基本数据类型那样单纯表示数值,
swift中 基本数据类型和集合全部由结构或枚举实现,虽然牺牲了性能,但是功能却强大了很多。
基本数据类型
- 整型(Int8,Int16,Int32,Int64,Int(32位平台与Int32等宽,64位平台与Int64等宽),UInt8,UInt16,UInt32,UInt64,UInt)
- 浮点型(Float, Double)float 32位,double64位,默认浮点数为double
- 字符 let a:Character = "&" let b = "\u{1fb03}" 字符也用双引号
- 字符串 字符串拼接 let number = 9 ; let total = "\(number)加10等于\(Double(number) + 10)"
- 布尔型 Bool 只有两个值true,false,不能用0,1代替
元组(tuple)类型(记录)
var student1 = ("1001","张飞",20,96) 或 var student2 = (id:"1001",name:"张飞",age:20,score:96)
或 var student3 : (String,String,Int,Int) ; student3 = ("1001","张飞",20,96)
访问元组字段: student1.0, student2.0,student2.id
枚举
结构
类
typealias MyInt = Int
var x :MyInt = 10
swift 中除类以外,所有基本数据类型,集合都是由结构实现,所有都可以调用构造器来初始化
let x = Float() //0.0
let y = Double() //0.0
let z = Int() //0
let aa = Bool()//false
let bb = Character("S") //Character没有无参初始化
let dd = String() //""
let ee = [Int]()//0 elements
let ff = [Int:String]()//0 key/value pairs
let gg = Set<String>() //0 members
let xxx: () = ()
swift里除了类以外的基本类型都是由结构体实现的,也既是除了类以外都是值引用类型
不再支持数字类型的隐式转换
let pi = 3 + 0.1415926 // pi的类型推导为double(最大精度匹配原则) let anInt = 10
let aDouble = 3.14
//var result = anInt + aDouble //报错
var result = Double(anInt) + aDouble let aChar:Character = "a"
//var a:Character = anInt + aChar //报错
//var b:Int = a //报错
- Int8.min,Int8.max
- 二进制:0b,八进制:0o,十六进制:0x,指数:1.56e-2; 十六进制指数 0x5.a2p2(0x5.a2 * 22)
- swift 为方便阅读,整形,浮点均可添加多个零或下划线以提高可读性 var a = 000.0145 ; var b = 3_360_000
// 整形 let a = 100
a.byteSwapped
a.bigEndian
a.littleEndian
a.toIntMax()
a.value
a.advancedBy(100)
a.description
字符Character,字符串String 都使用""
String 本质上是一个Struct,因此可以用构造器来创建字符串
var str1 = "2sfer"
var str2 = String()
var str3 = String(count:5,repeatedValue:Character("f"))
let character:Character = "a"
let str4 = String(character)
let characters:[Character] = ["c","b","a"]
let str5 = String(characters)
字符串日常操作:是否包含某字符,rangOfString,前后缀,大小写切换,分割等
let someone = "Joris Kluivers" let end2 = someone.rangeOfString(" ")//5..<6
if (end2 != nil) {
let firstName = someone[someone.startIndex..<end2!.startIndex] //"Joris"
} else {
// no space found
} // 前后缀
let doc = "Java.docx"
if doc.hasSuffix(".docx"){}
if doc.lowercaseString.hasPrefix("java"){} // 大小写
"Hello, playground".uppercaseString //HELLO, PLAYGROUND
"Hello, playground".lowercaseString //hello, playground // 分割
"Hello, playground".componentsSeparatedByCharactersInSet(
NSCharacterSet(charactersInString: "eo")
) //["H", "ll", ", playgr", "und"]
"Hello, playground".componentsSeparatedByString("play")//["Hello, ", "ground"]
var cafe = "cafe"
// 插入字符
cafe.insert("!", atIndex: cafe.endIndex) // "cafe!"
// 插入字符串
cafe.insertContentsOf(" is delicious".characters , at: cafe.endIndex.predecessor())//"cafe is delicious!" //移除字符
cafe.removeAtIndex(cafe.endIndex.predecessor()) // "!"
//移除字符
cafe.removeRange(cafe.startIndex.advancedBy(1)...cafe.startIndex.advancedBy(3))// "c is delicious" //替换 ,移除字符单位置还在
cafe.replaceRange(cafe.startIndex.advancedBy(1)...cafe.startIndex.advancedBy(3), with: "afe") //"cafe delicious"
swift中每一个字符都代表了一个可扩展字母集(Extended Grapheme Clusters)
每一个可扩展的字母集,又由一个或几个有序的Unicode标量的值(Unicode scalar value)所组成,以上这些构成了人类可读的字符。
//形同c中用ascii编码,swift用unicode编码,
一个unicode标量占21个bit,
取值范围,U+0000到U+D7FF和从 U+E000 到U+10FFFF,不包括 U+D800 到 U+DFFF
let dollarSign = "\u{24}"
let blackHeart = "\u{2665}"
String 用结构实现,是值类型,而NSString 用类实现,是引用类型
String.Characters.count,和 NSString.length 并不总是完全一样的值,因为前者统计的是有意义的Extended Grapheme Clusters 个数,后者是UTF-16编码 计数
var word = "cafe"
word.characters.count // 4
(word as NSString).length // 4 word += "\u{301}" // "café", 组合了一个重音符号
word.characters.count // 4
(word as NSString).length // 5 word += "\u{301}" // "café́", 再组合了一个重音符号
word.characters.count // 4
(word as NSString).length // 6 word += "\u{301}" // "café́́", 再组合了一个重音符号
word.characters.count // 4
(word as NSString).length // 7 word += "\u{301}" // "café́́́", 再组合了一个重音符号
word.characters.count // 4
(word as NSString).length // 8 word += "\u{301}" // "café́́́́", 再组合了一个重音符号
word.characters.count // 4
(word as NSString).length // 9 word += "\u{20dd}" // "café́́́́⃝", 再组合了一个圆
word.characters.count // 4
(word as NSString).length // 10 var decomposed:Character = "\u{1112}\u{1161}\u{11ab}" // "한" 由三个Unicode标量组成,但是一个字符 var decomposedString:String = "\u{1112}\u{1161}\u{11ab}" // 用 for in 遍历字符串
for c in decomposedString.characters{
print(c) // "한", 只有一个字符
} //用下标遍历
let end = decomposedString.endIndex // 3 最后一个Unicode标量的位置+1
var i = decomposedString.startIndex // 0
i.advancedBy(1) // 3 for(var j = decomposedString.startIndex;j<end;j=j.successor()){
print(decomposedString[j])
} let NSdecomposedString = decomposedString as NSString
for var i = 0; i < NSdecomposedString.length; i++ {
//3 times (4370, 4449, 4523)
print(NSdecomposedString.characterAtIndex(i))
} let u1 = UnicodeScalar(4370) // 4370
let u2 = UnicodeScalar(4449) // 4449
let u3 = UnicodeScalar(4523) // 4523
let c1 = Character(u1) // ᄒ
let c2 = Character(u2) // ᅡ
let c3 = Character(u3) // ᆫ
let c = Character("\(c1)\(c2)\(c3)") // 한
swift中字符串的比较会 比对每个字符的语义和最终表现形式。而不是比对构成字符的标量
let word1 = "caf\u{e9}" // "café" \u{e9} 带音调的拉丁字母e
let word2 = "caf\u{65}\u{301}" // "café" \u{65}\u{301} 拉丁字母e + 一个重音符号
word1 == word2 // true
// 转化为 NSString 后比对
(word1 as NSString) == (word2 as NSString) // false let a1 = "\u{41}" // 拉丁字母 A
let a2 = "\u{0410}" // 斯拉夫字母 A
a1 == a2 // false
子字符串:无法用Int下标来访问String中的字符或字串,而使用String.Index
var imageStr = "swift 学习(一)基础知识 (基本数据类型,操作符,流控制,集合)的更多相关文章
- jQuery学习笔记 - 基础知识扫盲入门篇
jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...
- Ant学习-001-ant 基础知识及windows环境配置
一.Ant 概要基础知识 Apache Ant 是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发,用以构建应用,或结合其他开源测试工具例如 git.T ...
- 01-Java基础知识:数据类型与变量、标识符、运算符、表达式
Java基础知识:数据类型与变量.标识符.运算符.表达式 一.数据类型 Java定义了基本数据类型.引用数据类型.自定义类型. 八种基本数据类型:byte (1). short (2). int ( ...
- 学习javascript基础知识系列第二节 - this用法
通过一段代码学习javascript基础知识系列 第二节 - this用法 this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascr ...
- 学习javascript基础知识系列第三节 - ()()用法
总目录:通过一段代码学习javascript基础知识系列 注意: 为了便于执行和演示,建议使用chrome浏览器,按F12,然后按Esc(或手动选择)打开console,在console进行执行和演示 ...
- 关于图计算&图学习的基础知识概览:前置知识点学习(Paddle Graph Learning (PGL))
关于图计算&图学习的基础知识概览:前置知识点学习(Paddle Graph Learning (PGL)) 欢迎fork本项目原始链接:关于图计算&图学习的基础知识概览:前置知识点学习 ...
- Python基础知识(六)------小数据池,集合,深浅拷贝
Python基础知识(六)------小数据池,集合,深浅拷贝 一丶小数据池 什么是小数据池: 小数据池就是python中一种提高效率的方式,固定数据类型使用同一个内存地址 代码块 : 一个文 ...
- [SQL] SQL 基础知识梳理(七)- 集合运算
SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...
- 学习Python3基础知识过程中总结
print()中end==""的用法 例子:用Python3输出九九乘法表: for i in range(1,10): for j in range(1,i+1): s=i*j ...
- three.js学习笔记--基础知识
基础知识 从去年开始就在计划中的three.js终于开始了 历史介绍 (摘自ijunfan1994的转载,感谢作者) OpenGL大概许多人都有所耳闻,它是最常用的跨平台图形库. WebGL是基于Op ...
随机推荐
- u3d_shader_surface_shader_5
CubeMap 的实现 参考: http://blog.csdn.net/candycat1992/article/details/21827365 制作cubeMap三维纹理,surface ...
- Sphinx和coreseek检索引擎
Sphinx是检索英文用,coreseek是检索中文用. Sphinx(斯芬克斯)是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索 ...
- JProfiler学习笔记
JProfiler学习笔记 一.安装JProfiler 从http://www.ej-technologies.com/下载5.1.2并申请试用序列号 二.主要功能简介 1.内存 ...
- java 26 - 8 网络编程之 TCP协议上传图片
上次的是上传TXT文件,这次上传的是图片.同样,上传成功需要反馈给客户端. 区别: TXT文件用记事本打开,我们可以看得懂,所以用了缓冲字符流,对通道内的字节流进行包装了. 而图片用记事本打开,我们看 ...
- Android系统自带APP分析——短信app
Android操作系统本身就是一个巨大的开源软件仓库,熟悉它既可以了解到Android系统的设计框架,也可以获得高效的应用程序编写方式.本文所分析的源码来自于Google官方的AOSP源码4.0.1_ ...
- tomcat相关配置技巧梳理
tomcat常用架构:1)nginx+tomcat:即前端放一台nginx,然后通过nginx反向代理到tomcat端口(可参考:分享一例测试环境下nginx+tomcat的视频业务部署记录)2)to ...
- OSWatcher Black Box
Linux监控工具介绍系列--OSWatcher Black Box OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小 ...
- java:如何让程序按要求自行重启?
正文开始前的废话: 这里的程序即包括b/s的web application,也包括standalone的类c/s的java application. 为什么要自我重启? 场景1:分布式环境中, ...
- 前端见微知著JavaScript基础篇:你所不知道的apply, call 和 bind
在我的职业生涯中,很早就已经开始使用JavaScript进行项目开发了.但是一直都是把重心放在了后端开发方面,前端方面鲜有涉及.所以造成的一个现象就是:目前的前端知识水平,应付一般的项目已然是足够的, ...
- TinyFrame升级之五:全局缓存的设计及实现
在任何框架中,缓存都是不可或缺的一部分,本框架亦然.在这个框架中,我们的缓存分为两部分:内存缓存和单次请求缓存.简单说来,就是一个使用微软提供的MemoryCache做扩展,并提供全局唯一实例:另一个 ...