当前位置: 首页 > news >正文

Swift - 37 - 值类型和引用类型的简单理解

//: Playground - noun: a place where people can play

import UIKit

// 值类型:指的是当一个变量赋值给另外一个变量的时候, 是copy一个副本
// 两个变量之间互不影响, 也就是说, 另外一个变量的值改变, 不会影响到另外一个变量
// 也就是传的只是一个值, 不是一个引用(地址)
var a = 0
var b = a
b = 2
a

// 闭包和函数都是引用类型
// 引用类型:指的是当引用类型变量赋值给另外一个变量的时候, 其实两个变量指的都是同一个内容
// 当其中一个变量修改了这个内容, 另外一个变量也会跟着改变
func calcTotalMiles(todayMiles: Int) -> () -> Int
{
    var totalMiles = 0
    return {
        totalMiles += todayMiles;       // 这个闭包用到了Capturing Values
        return totalMiles
    }
}

var dailyTwoMiles = calcTotalMiles(2)
dailyTwoMiles()
dailyTwoMiles()

var myPlan = dailyTwoMiles
myPlan()
myPlan()

/*
同学A的理解:
var totalMiles = 0 这句是处在 calcTotalMiles 函数中。
而你说的每次调用,调用的并不是 calcTotalMiles 这个函数,
而是 calcTotalMiles 这个函数的返回值,也就是另一个函数。
返回的函数被命名为 dailyTwoMiles 或者 dailyThreeMiles,
返回函数的内容是闭包内容:{totalMiles += todayMiles; return totalMiles; },
其中并没有对 totalMiles 重置的语句,所以totalMiles不会被重置。
那么问题来了,totalMiles 什么时候被重置。
很简单,var totalMiles = 0 处在 calcTotalMiles 函数中,
当然是 calcTotalMiles 被调用时会被重置,
也就是 
var dailyTwoMiles = calcTotalMiles(2) 和 
var dailyThreeMiles = calcTotalMiles(3) 
这两句在运行时会重置 titalMiles.

同学B的理解:
这里的关键是:calcTotalMiles返回了一个函数,这个函数以闭包的形式返回,我们没有给他起名,
这里姑且叫他resultFunction。要注意,这个resultFunction和calcTotalMiles不是一个东西,
resultFunction是calcTotalMiles的一个结果!
仔细看这个resultFunction函数体内,涉及的两个变量:totalMiles和todayMiles,
都没有在resultFunction里定义。那resultFunction是怎么拿到这个值的呢?
这个过程是swift使用一种称为Capturing Values的方式感知到的。与此同时,一点儿没有错,这将产生内存方面的问题。
在这里,你可以理解成,我们给calcTotalMiles传入一个参数,返回了一个函数resultFunction,
之后执行calcTotalMiles所使用的栈空间并没有被释放,因为产生的resultFunction还在使用(或者是拥有)调用者calcTotalMiles的内容。

我个人的理解是:
由于calcTotalMiles的返回值是resultFunction, 而resultFunction又引用着calcTotalMiles中的变量, 
所以calcTotalMiles执行完之后并没有被销毁, 还保留在内存中...
所以当resultFunction再次调用的时候所拿到的totalMiles还没有被初始化..就会继续累加...
*/

// ps: 在实际中, 很少用到函数和闭包是引用类型这种情况, 这里仅仅作为了解...

  

转载于:https://www.cnblogs.com/Rinpe/p/5173368.html

相关文章:

  • 算法导论 第六章 2 优先队列(python)
  • gdb跟踪应用程序原理浅析
  • ORACLE 11G内存管理方式
  • 正则表达式总结
  • Cocos2d-js使用ETC1格式的图片
  • 2015年年终总结
  • Java实现多线程邮件发送
  • [算法]需要排序的最短子数组长度
  • 面向对象编程(十四)——面向对象三大特性之多态①
  • 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。...
  • java设计模式之——适配器模式
  • 工具-常用工具
  • [Flex] PopUpButton系列 —— 控制弹出菜单的透明度、可用、可选择状态
  • javascript 变量声明有var与无var 的区别
  • 我理解的this
  • Android Studio:GIT提交项目到远程仓库
  • css的样式优先级
  • CSS盒模型深入
  • exports和module.exports
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Linux快速复制或删除大量小文件
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • windows下如何用phpstorm同步测试服务器
  • 读懂package.json -- 依赖管理
  • 翻译--Thinking in React
  • 分布式事物理论与实践
  • 分类模型——Logistics Regression
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 记一次和乔布斯合作最难忘的经历
  • 浏览器缓存机制分析
  • 容器服务kubernetes弹性伸缩高级用法
  • 三分钟教你同步 Visual Studio Code 设置
  • 三栏布局总结
  • 数据可视化之 Sankey 桑基图的实现
  • 网页视频流m3u8/ts视频下载
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 正则表达式-基础知识Review
  • $GOPATH/go.mod exists but should not goland
  • (1)常见O(n^2)排序算法解析
  • (2)STM32单片机上位机
  • (23)Linux的软硬连接
  • (4.10~4.16)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (Oracle)SQL优化技巧(一):分页查询
  • (pojstep1.1.2)2654(直叙式模拟)
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (二)c52学习之旅-简单了解单片机
  • (附源码)计算机毕业设计大学生兼职系统
  • (强烈推荐)移动端音视频从零到上手(下)
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (算法)前K大的和
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET 使用配置文件