swift1.1-常量和变量

定义

  • let被用于声明不变量,不变量的值一旦被定义就不能再改变
  • var被用于声明变量,变量则可以在声明之后被随意赋值。

let & var 对比

变量名

变量声明

常量和变量名可以包含任何字符,包括 Unicode 字符.

常量与变量名不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符。也不能以数字开头,但是可以在常量与变量名的其他地方包含数字。
一旦你将常量或者变量声明为确定的类型,你就不能使用相同的名字再次进行声明,或者改变其存储的值的类型。同时,你也不能将常量与变量进行互转。

声明

在这里插入图片描述

类型注解

类型注解(type annotation),说明常量或者变量中要存储的值的类型。
如果要添加类型注解,需要在常量或者变量名后面加上一个冒号和空格,然后加上类型名称。

类型注解

背后的编程模式

变量和不变量其实源于两种不同编程范式。编程范式是编程语言设计者所持有的“世界观”的反映。

变量来源于***命令式编程范式***。这种编程范式将世界视为一系列独立的对象的组合,这些对象的行为可能会随着时间变化而不断变化。程序语言中的变量被用于模拟对象的状态。

不变量来源于***函数式编程范式***。这种编程以数学函数为建模核心。试图将世界抽象成为以一系列数学函数。数学函数中的变量其实和命令式编程语言中的变量存在着显著的区别。基于数学的函数式编程中的变量的概念更接近于命令式编程中的不变量。

我们甚至可以通过对变量的态度来定义命令式编程和函数式编程:广泛采用赋值的程序设计被称为命令式程序设计;不使用任何被赋值的程序设计被称为函数式程序设计。这是因为,赋值操作使得变量可变。没有赋值操作,则变量不可变。

Swift受到了函数式编程的影响,强化了不变量在语言中位置,鼓励不变量的使用.

在其它一些如Java,C这样的命令式编程语言中也有不变量的概念。但多数情况下会被以常量形式使用,常量是静态的不变量。在Java中,通常用static和final一起来定义常量,其中static用于指明其是静态的,final用于指明其是不变的。Java中,我们有多种定义常量的方法:接口中定义,类中定义,使用枚举实现。这些方法之间的区别是在何时何地如何使用static和final。Objective-C,则和C语言一样,使用const关键字说明一个变量不应被改变。

在这类语言中,不变量和变量相比,通常是不寻常的,次一等的概念。如果将一个名字关联到一个值,缺省的会得到一个变量,而不是不变量。如果,你需要一个不会改变,一直和某个特定值绑定的名字,就需要显式说明它是不变的。例如,在Java中使用final,在C中使用const。这种缺省就是变量的情况,甚至影响了我们的语言。当我们需要描述,“声明用于和某个值关联的名字”时,我们说的是“声明变量”。但其实,这个“变量”应该加上引号,因为它其实可能是个不变量。这和指代不明确性别人时,使用“他”而不是“她”是同一类现象。

“缺省的是变量,如果需要不变量,请显式说明”。这是大多数命令式编程语言对变量和不变量的处理方法。这很自然。因为这类语言的设计中,大多数情况下使用的是变量,不变量只是在特殊情况下才需要。Swift(和Scala一样)则对这种设计做出了修改。从缺省是变量,转变为认为变量和不变量的地位是平等的。不变量应该更多被提倡和使用。在Swift的语法中,对这种设计思想的体现是:在定义一个和值关联的名字时,需要明确地使用var或let说明它是变量还是不变量。

函数式编程中的变量

函数式编程以数学函数为建模基础。其变量的概念和数学中变量的概念是一致的。所以,我们可以先回顾一下数学函数中变量的概念。由于现在绝大多数程序设计语言是命令式的,所以我们通常所说的变量是命令式编程中的定义,这和数学函数中的变量并不相同。

在数学中,函数是描述每个输入值对应唯一输出值的这种对应关系。数学函数中的变量是一个用于表示值的符号,值是可以是随意的,也可能是未定的。所以,在数学函数中,某个符号我们之所以称其为变量,是因为它可以用于代表不同的值。而需要指明的是:当我们用明确的数值代入函数运算时,变量就拥有了明确的值。而在一次代换过程中,变量一旦被代换为明确的值,就不会再次改变为其它值。数学函数中不存在这种情况:某一次代换过程中,某个变量x一开始被代换为2,然后又变为3。这在数学上,没有任何意义。

这样看起来,数学函数中的变量其实应该可以对应程序语言中的不变量:一旦被定义,就不再变化。纯粹的函数式编程语言就完整继承了这种数学上的变量概念。例如,Haskell就没有可变量的概念,声明一个变量,只能被赋值一次,之后就不会再变化。而命令式编程语言中,变量被定义之后,仍然能够随意被赋予其它的值。

比如我们有一个简单的数学函数:
[外链图片转存失败(img-KuRUMIhP-1564660394030)(media/15638818458293/15638861924833.jpg)]

如果,我们遵循数学函数对变量的看法,可以将其翻译为如下的Swift函数。这个程序函数和上面的数学函数,在概念上是等价的。
[外链图片转存失败(img-lpb3QMn0-1564660394031)(media/15638818458293/15638863333727.jpg)]

当然,这个Swift函数foo,还有其它现实方法。函数的另外一种实现bar为了展示y是一个命令式编程里的变量,而稍显怪异。但它仍然能得到和上面的函数相同的答案:代入任意相同的x值,两个函数都会得到相同的返回值。但由于数学函数中不存在y这样的一开始等于某个值,而后又被赋为另一个值这样的命令式编程中的变量概念。所以,我们没有办法将下面这样的Swift函数bar还原为一个概念上一致的数学函数。

[外链图片转存失败(img-5VyHGiIc-1564660394031)(media/15638818458293/15638864942759.jpg)]

Swift中提供let声明不变量,更为重视不变性,明确鼓励在更多的场合使用不变量。这都是受函数式编程中变量的不变性的影响。

##命令式编程中的变量
命令式编程语言中的变量的概念为大多数程序员所熟悉。我们将其和函数式编程中的变量做一个对比:在函数式编程中,变量其实并不可变,这种变量只是一个代表了某个值的符号。而在命令式编程中,由于变量是可变的,变量就不仅仅是简单代表一个值的符号,而是索引了一个可以保存值的位置,在这个位置上可以存放不同的值。

我们的世界中每个对象都有着自己随着时间变化的状态。而在不同时刻,变量可以代表了不同的值,使得变量拥有了时序上的概念。我们就可以使用变量来模拟和刻画现实世界中的对象的状态。这其实也是为何会引入赋值,使得变量可变的原因。

引入赋值的好处

如果使用过一些函数式编程语言,就会发现部分函数式编程语言并没有完全抛弃赋值。为何这些函数式编程语言没有完整地贯彻变量的不变性呢?

函数式编程语言出现的时间很早,最早的函数式编程语言Lisp是历史第二悠久的高级编程语言(仅次于Fortran)。但现在函数式编程语言并没有成为绝大多数程序员的工作语言。为何现今流行的编程语言:C,Java,C++,Python都是命令式编程语言呢?

这是因为,引入赋值,使得变量可变。就引入了一个简单直观又易于模块化的程序语言建模方法。这在设计大型软件系统时是一个巨大的优势。

命令式编程的建模思想是一种直观的世界观:“世界是由聚集在一起的一系列独立的对象组成的”。但这仅仅是在一个维度上的描述。另外一个时间维度上的描述通常不被提及:“每个对象都有着随时间变化的状态”。综合来说就是:“世界由对象组成,对象都有状态”。将这种直观的世界观引入程序设计所带来的好处是,建模更为简单了。使用这种思想的编程语言对于程序员来说也更为简单直观了。那么将一个实际问题用这种编程语言中的概念来描述,也就变得更轻松了。因为,程序员通常能够为实际问题中的事物一一对应地构建对象,并按时序描述每个对象的状态。

如果将赋值和局部变量结合,构造带局部状态的对象,就可以提供一种有利于系统模块化设计的技术。这是一种强大的设计策略,原因在于它的简单和直观。我们可以直接构造那些用于模拟真实物理系统的对象。对于问题域里的每个对象,我们都可以构造一个与之相对应的计算机程序里的对象。如果,我们能把对象的“状态”局限在对象内部,使之成为“局部状态”(这其实就是封装)。然后,将各自具有“局部状态”的对象组合,这会是一个良好的模拟真实世界的手段。

我们之所以可以使用UML(Unified Modeling Language,统一建模语言)来分析项目需求,是因为我们将在项目中使用命令式编程语言。从UML这种图形化的辅助建模方式中,我们可以更明显地看到如何将真实世界中的对象和程序语言中的对象一一对应,如何将真实世界中的对象的一个个属性和程序语言中的对象的变量一一对应。

如果,使用函数式编程语言,UML将不再能起到任何作用。你需要的是一个类似将现实问题抽象为数学问题的过程。这种数学的建模方式对大多数人来说可能都会更为困难一些。

更复杂的计算模型

为函数式编程语言引入赋值语句,使得变量可变。看起来只是多了赋值语法,但其实这并不是一件简单的事情。赋值的引入对编程语言造成的影响是巨大的:随着赋值的引入,我们必须为编程语言引入一种更为复杂的计算模型。

在没有赋值语句之前,纯函数式编程语言可以使用数学上的代换模型来构建语言的计算模型:一个变量可以安全地被代换为它所代表的表达式或者值。求值一个纯函数式编程语言中的函数,和求值一个数学函数并没有什么区别。你可以认为编程语言的运行方式和数学的运算方式是一样的。这种代换模型其实是一个相当简单的语言模型。

但在引入赋值之后,变量在程序运行的某些时刻代表一个值,在另一些时刻代表另外一个值。代换模型就不再有效了。因为,代换模型基于数学模型。数学上并没有在某些时刻代表一个值,在另一些时刻代表另外一个值的变量概念。如果尝试对带有赋值操作的函数进行代换,会发现当遇到赋值语句时,代换过程无法进行下去。因为变量已经不能被再被看做是某个值的名字了。此时的变量以某种方式指定了一个“位置”,我们可以将任何值存储在该“位置”。那到底是将哪个值代入变量呢?在代换模型中,无法解决该问题。

为了解决这个问题,我们引入更为复杂的环境模型。变量将维持在我们称为“环境”的结构中。环境包含一系列约束,这些约束将一些变量的名字关联到对应值。在环境模型中,变量的值将取决于其所处的环境。程序运行过程中,环境时常变化,变量的值也就随之改变。

引入更复杂的计算模型意味着实现编程语言变得更为困难了。

总结:

Swift对这两种编程思想进行了融合:**它允许你使用引入赋值所带来的简单直观的建模方法。**同时也鼓励你使用不变性缓解各类并发问题。

函数入口

原main函数:
@UIApplicationMain

自定义入口main函数:
在这里插入图片描述

输出

let π = 3.1415926
let 你好 = "你好forin"
let ? = "smile"
print(π,你好)
print(π,你好, separator: ", ", terminator: ":)")

注释

通过运用嵌套多行注释,你可以快速方便的注释掉一大段代码,即使这段代码之中已经含有了多行注释块。

// 单行注释

/**
 多行注释
 */

/*
 这是第一层注释
 
 /*
 这是第二层注释
 */
 
 */

文档注释


/**
 In this playground, I will show you how to use swift built-in comment syntac to create documentation. It's quite useful when your program is large or you need to share your code to co-works.
 
 Basically speaking, you can use the /** ... */ for mutiline comments or /// for single-line comments. Inside comment blcoks, basic **Markdown** syntax applied:
 
 - Paragraphs are seperated by blank lines
 - Unordered lists can use a variety of bullet characters: -, +, *. This sample is in an unordered list.
 - Ordered lists use Arabic numerals followed by a period 1., as follows
 
 1. item 1
 2. item 2
 3. item 3
 */

参数返回值等注释

enum MyError: Error{          //swift 3
    case BothNilError
    case JustImpossible
}

/// There are a few keywords Xcode can recognize automatically. The format is like **- <Keyword>**:. The most common use one is **Parameter**, **Throws** and **Returns**.
/// - Parameter item1: This is item1
/// - Parameter item2: This is item2
/// - Throws: `MyError.BothNilError` if both item1 and item2 are nil.
/// - Returns: the result string.
func showKeywordsCommentsWithItem1(item1: AnyObject?, item2: AnyObject?) throws -> String {
    
    if item1 == nil && item2 == nil{
        throw MyError.BothNilError
    }
    
    let text = "There are a few keywords Xcode can recognize automatically."
    return text
}

/// There are a few keywords Xcode can recognize automatically. The format is like **- <Keyword>**:. The most common use one is **Parameter**, **Throws** and **Returns**.
///
/// - Parameters:
///   - item1: This is item1
///   - item2: This is item2
///
/// - Throws: `MyError.BothNilError` if both item1 and item2 are nil.
///
/// - Returns: the result string.
func showKeywordsCommentsWithItem2(item1: AnyObject?, item2: AnyObject?) throws -> String {
    
    if item1 == nil && item2 == nil{
        throw MyError.BothNilError
    }
    
    let text = "There are a few keywords Xcode can recognize automatically."
    return text
}

算法的注释

/// For algorithms or other use, you can use some other keywords, such as `Precondition`, `Postcondition`, `Requires`, `Invariant`, `Complexity`, `Important` and `Warning`.
///
/// Suppose here we have a mysterial algorihtm
///
/// - Precondition: The object must contain all the information in the world.
/// - Postcondition: After the algorithm, the object will contain all the information in the universe.
/// - Requires: All the information in the object should be sorted.
/// - Invariant: The object will maintain sorted.
/// - Complexity: O(n^n)
/// - Important: Please only call this algorithm once in your program.
/// - Warning: Very computation consuming.
/// - Attention: Same as Warning.
/// - Note: I terribly doubt this algorihtm.
/// - Remark: Same as Note.
///
/// - Parameter object: The algorithm will use this single object to change the world.
/// - Throws: `MyError.JustImpossible` if the algorithm's precondition can not be satisfied.
/// - Returns: the object contains all the information in the universe.
func mysteriousAlgorithm(object: AnyObject) {
    
    return
}

源数据注释

/// Some meta information can be added into the comment documentation using **author**, **authors**, **copyright**, **date**, **since**, **version**
///
/// This is an example
/// - Author: liuyubobobo
/// - Authors: All the geeks in the world:)
/// - Copyright: liuyubobobo@2016
/// - Date: 26 Jan, 2016
/// - Since: iOS 5
/// - Version: 3.1415926
func showMetaComments() -> String{
    let text = "Hello, comments:)"
    return text
}

Mark / TODO / FIXME

    // TODO: Offer a all parameters initializer
    // MARK: - Methods
	// FIXME: Support Swift 2.2

分号

Swift 并不强制要求你在每条语句的结尾处使用分号(;),当然,你也可以按照你自己的习惯添加分号。有一种情况下必须要用分号,即你打算在同一行内写多条独立的语句

let π = 3.1415926 ;let 你好 = "你好forin"
【资源说明】 1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通。 2.主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。 5.期待你能在项目中找到乐趣灵感,也欢迎你的分享反馈! 本文介绍了基于QEM(Quadric Error Metrics,二次误差度量)的优化网格简化算法的CC++实现源码及其相关文档。这一算法主要应用于计算机图形学领域,用于优化三维模型的多边形数量,使之在保持原有模型特征的前提下实现简化。简化的目的是为了提高渲染速度,减少计算资源消耗,以及便于网络传输等。 本项目的核心是网格简化算法的实现,而QEM作为该算法的核心,是一种衡量简化误差的数学方法。通过计算每个顶点的二次误差矩阵来评估简化操作的误差,并以此来指导网格简化过程。QEM算法因其高效性准确性在计算机图形学中广泛应用,尤其在实时渲染三维打印领域。 项目代码包含CC++两种语言版本,这意味着它可以在多种开发环境中运行,增加了其适用范围。对于计算机相关专业的学生、教师行业从业者来说,这个项目提供了丰富的学习实践机会。无论是作为学习编程的入门材料,还是作为深入研究计算机图形学的项目,该项目都具有实用价值。 此外,项目包含的论文文档为理解网格简化算法提供了理论基础。论文详细介绍了QEM算法的原理、实施步骤以及与其他算法的对比分析。这不仅有助于加深对算法的理解,也为那些希望将算法应用于自己研究领域的人员提供了参考资料。 资源说明文档强调了项目的稳定性可靠性,并鼓励用户在使用过程中提出问题或建议,以便不断地优化完善项目。文档还提醒用户注意查看,以获取使用该项目的所有必要信息。 项目的文件名称列表中包含了加水印的论文文档、资源说明文件实际的项目代码目录,后者位于名为Mesh-Simplification-master的目录下。用户可以将这些资源用于多种教学研究目的,包括课程设计、毕业设计、项目立项演示等。 这个项目是一个宝贵的资源,它不仅提供了一个成熟的技术实现,而且为进一步的研究学习提供了坚实的基础。它鼓励用户探索扩展,以期在计算机图形学领域中取得更深入的研究成果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值