第三章:R语言编程 第五节:值传递对象不变性

2024-03-06 06:20

本文主要是介绍第三章:R语言编程 第五节:值传递对象不变性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、值传递

在R语言中,一切皆为对象,同时在调用函数的时候也采用值传递的方式,即作为参数的对象会被复制,然后将副本传递给函数

例如:

> f<-function(df2){
+   df2$a<-c(1,2,3)
+ }
> df<-data.frame(a=c(4,5,6))
> f(df)
> dfa
1 4
2 5
3 6

这里将数据框作为参数传递给函数的时候,函数内部的修改将不会影响原对象。这是因为调用f()函数时采用的时值传递的方法;df2中保持的不是指向原始数据df的引用,而是复制数据框df,df2指向的是副本数据框

如果我们想让函数内部的改动影响到函数外部,则需要在函数f()内部用返回值修改语句,然后再将函数的返回值的修改结果赋值给原来的变量

例如:

> f<-function(df2){
+   df2$a<-c(1,2,3)
+   return(df2)
+ }
> df<-data.frame(a=c(4,5,6))
> df<-f(df)
> dfa
1 1
2 2
3 3

因此我们可以得出结论,除了特殊对象以外,对象状态不会被函数直接修改,无论哪种函数能能保证参数传递的对象不被修改

PS:这一部分我觉得结合C++中指针那一块的内容食用更佳

二、对象不变性

R中的对象通常是不变的,在编程中,值不变意味着数值不能被修改

例如:

> a<-list()
> a$b<-c(1,2,3)

这则代码实际上进行的步骤是先复制a,创建新对象a',然后向对象a'添加属性b,再将c(1,2,3)填充到b,最后让变量名指向a'。

而并非在a中直接开辟一个新属性b,让后将c(1,2,3)复制给b

我们利用对象复制追踪函数tracemem()进行查看

> a<-list()
> tracemem(a)
[1] "<000001D6746E3A80>"
> tracemem(a$b<-c(1,2,3))
[1] "<000001D6771B61E8>"

我们可以发现内存地址进行了更改,意味着其进行了复制导致内存地址增加

所以在R语言里使用循环语句是很不明智的,因为会导致内存占用不断增加吃掉太多资源,从而让效率降低,因此我们还是推荐使用向量来代替实现循环语句

例如我们要实现1~1000000全体加1

循环语句> v<-1:1000000
> for(i in 1:1000000)
+   v[i]<-v[i]+1执行完毕后会发现内存急速扩大利用向量> v<-1:1000000
> v<-v+1这样会快很多,而且占用资源更低

这篇关于第三章:R语言编程 第五节:值传递对象不变性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/779090

相关文章

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安

Java中对象的创建和销毁过程详析

《Java中对象的创建和销毁过程详析》:本文主要介绍Java中对象的创建和销毁过程,对象的创建过程包括类加载检查、内存分配、初始化零值内存、设置对象头和执行init方法,对象的销毁过程由垃圾回收机... 目录前言对象的创建过程1. 类加载检查2China编程. 分配内存3. 初始化零值4. 设置对象头5. 执行

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

异步线程traceId如何实现传递

《异步线程traceId如何实现传递》文章介绍了如何在异步请求中传递traceId,通过重写ThreadPoolTaskExecutor的方法和实现TaskDecorator接口来增强线程池,确保异步... 目录前言重写ThreadPoolTaskExecutor中方法线程池增强总结前言在日常问题排查中,

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

C#多线程编程中导致死锁的常见陷阱和避免方法

《C#多线程编程中导致死锁的常见陷阱和避免方法》在C#多线程编程中,死锁(Deadlock)是一种常见的、令人头疼的错误,死锁通常发生在多个线程试图获取多个资源的锁时,导致相互等待对方释放资源,最终形... 目录引言1. 什么是死锁?死锁的典型条件:2. 导致死锁的常见原因2.1 锁的顺序问题错误示例:不同

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤