Swiftc语言获取文件大小如何获取类型的大小

没有更多推荐了,
不良信息举报
举报内容:
初探swift语言的学习笔记一(基本数据类型)
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Swift中非可选的可选值类型处理方法详解
转载 &发布时间:日 09:11:11 & 作者:johnsundell
Optional是Objective-C没有的数据类型,是苹果引入到Swift语言中的全新类型,它的特点就和它的名字一样:可以有值,也可以没有值,当它没有值时,就是nil。下面这篇文章主要给大家介绍了关于Swift中非可选的可选值类型处理方法的相关资料,需要的朋友可以参考下。
在我们使用objective-c表示字符串信息的时候,可以用下面方法书写。
NSString *str = @"秋恨雪";
因为objective-c是弱类型语言,所以这里的str既可以是具体的字符串也可以是nil。但到了Swift中就不可以了,因为Swift是类型安全的语言,一个String类型的变量不可能既能是具体的字符串,又可以为nil(更严格的说String类型的内容只能是字符串)。所以,在Swift中有了可选类型的概念。(其实这一概念也是“借鉴”于其他编程语言,比如C#,只不过在C#中称之为可空类型)。
大家在初看Optionals的感觉很陌生,在我第一眼看到它的时候,我就在想...这是什么鬼...但是仔细想想的话,可选值Optionals类型的引入,为我们也带了便利.
可选值(optionals)无可争议的是 swift 语言中最重要的特性之一,也是和其他语言,例如 Objective-C 的最大区别。通过强制处理那些有可能出现 nil 的地方,我们就能写出更有预测性的以及更健壮的代码。
然而,有些时候可选值可能会致你于尴尬的境地,尤其是你作为开发者了解(甚至是有些猜测的成分在),有的特定变量始终是非空(non-nil)的,即使它是一个可选类型。例如,我们在一个视图控制器中处理视图的时候:
class TableViewController: UIViewController {
var tableView: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: view.bounds)
view.addSubview(tableView!)
func viewModelDidUpdate(_ viewModel: ViewModel) {
tableView?.reloadData()
这也是对于很多 Swift 程序员争论比较激烈的地方,程度不亚于讨论 tabs 和 spaces 的用法。有的人会说:
既然它是一个可选值,你就应该时刻使用 if let 或者 guard let 的方式进行解包。
然而另外一些人则采用完全相反,说:
既然你知道这个变量在使用的时候不会为 nil,使用 ! 强制解包多好。崩溃也要比让你的程序处于一个未知状态要好吧。
本质上来讲,我们这里讨论的是要不要采用防御性编程()的问题。我们是试图让程序从一个未知状态恢复还是简单的放弃,然后让它崩溃掉?
如果非得让我对这个问题给出一个答案的话,我更倾向于后者。未知状态真的很难追踪 bug,会导致执行很多不想执行的逻辑,采用防御性编程就会使得你的代码很难追踪,出现问题很难追踪。
但是,我不太喜欢给出一个二选一的答案。相反,我们可以寻找一些技术手法,用更精妙的方式的解决上面提到的问题。
它真的可选的吗?
那些可选类型的,但是被代码逻辑真实需要的变量和属性,实际上是架构瑕疵的一个体现。如果在某些地方确实需要它,但是它又不在,就会使得你的代码逻辑处于未知状态,那么它就不应该是可选类型的。
当然,在某些特定场景下,可选值确实很难避免(尤其是和特定的系统 API 交互的时候),那对于大部分这种情况,我们有一些技术来处理从而避免可选值。
lazy 要比非可选的可选值更好
某些属性的值需要在其父类创建之后再生成(比如视图控制器中的那些视图,应该在 loadView()或者 viewDidLoad()方法中被创建),对于这种属性要避免其可选类型的方法就是使用 lazy 属性。一个lazy属性是可以是非可选类型的,同时也不在其父类的初始化方法里被需要,它会在其第一次被获取的时候创建出来。
让我们改一下上面的代码,使用 lazy 来改造 tableView 属性:
class TableViewController: UIViewController {
lazy var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.frame = view.bounds
view.addSubview(tableView)
func viewModelDidUpdate(_ viewModel: ViewModel) {
tableView.reloadData()
这样,没有可选值了,也不会有未知状态咯🎉
适当的依赖管理要比非可选的可选值要好
可选值类型另外一种常用的场景就是用来打破循环依赖()。有的时候,你就陷入 A 依赖 B,B 又依赖 A 的情况,如下:
class UserManager {
private weak var commentManager: CommentManager?
func userDidPostComment(_ comment: Comment) {
user.totalNumberOfComments += 1
func logOutCurrentUser() {
user.logOut()
commentManager?.clearCache()
class CommentManager {
private weak var userManager: UserManager?
func composer(_ composer: CommentComposer
didPostComment comment: Comment) {
userManager?.userDidPostComment(comment)
handle(comment)
func clearCache() {
cache.clear()
从上面的代码,我们可以看到,UserManager 和 CommentManager 之间有一个循环依赖的问题,它们二者都没法假设自己拥有对方,但是它们都在各自的代码逻辑里依赖彼此。这里就很容易产生 bug。
那要解决上面的问题,我们创建一个 CommentComposer 来做一个协调者,负责通知UserManager 和 CommentManager二人一个评论产生了。
class CommentComposer {
private let commentManager: CommentManager
private let userManager: UserManager
private lazy var textView = UITextView()
init(commentManager: CommentManager,
userManager: UserManager) {
self.commentManager = commentManager
self.userManager = userManager
func postComment() {
let comment = Comment(text: textView.text)
commentManager.handle(comment)
userManager.userDidPostComment(comment)
通过这种形式,UserManager 可以强持有 CommentManager 也不产生任何依赖循环。
class UserManager {
private let commentManager: CommentManager
init(commentManager: CommentManager) {
self.commentManager = commentManager
func userDidPostComment(_ comment: Comment) {
user.totalNumberOfComments += 1
我们又一次的移除了所有的可选类型,代码也更好预测了🎉。
优雅的崩溃(Crashing gracefully)
通过上面几个例子,我们通过对代码做一些调整,移除了可选类型从而排除了不确定性。然而,有的时候,移除可选类型是不可能的。让我们举个例子,比如你在加载一个本地的包含针对你 App 的配置项的 JSON 文件,这个操作本身一定会存在失败的情况,我们就需要添加错误处理。
继续上面这个场景,加载配置文件失败的时候继续执行代码就会使得你的 app 进入一个未知状态,在这种情况下,最好的方式让它崩溃。这样,我们会得到一个崩溃日志,希望这个问题能够在用户感知之前早早的被我们的测试人员以及 QA 处理掉。
所以,我们如何崩溃。。。最简单的方式就是添加 ! 操作符,针对这个可选值强制解包,就会在其是 nil 的时候发生崩溃:
let configuration = loadConfiguration()!
虽然这个方法比较简单,但是它有个比较大的问题,就是一旦这段代码崩溃,我们能得到的只有一个错误信息:
fatal error: unexpectedly found nil while unwrapping an Optional value
这个错误信息并不告诉我们为什么发生这个错误,在哪里发生的,给不了我们什么线索来解决它。这个时候,我们可以使用 guard 关键字,结合 preconditionFailure() 函数,在程序退出的时候给出定制消息。
guard let configuration = loadConfiguration() else {
preconditionFailure("Configuration couldn't be loaded. " +
"Verify that Config.JSON is valid.")
上面这段代码发生崩溃的时候,我们就能获得更多更有效的错误信息:
fatal error: Configuration couldn't be loaded. Verify that Config.JSON is valid.: file /Users/John/AmazingApp/Sources/AppDelegate.swift, line 17
这样,我们现在有了一个更清晰的解决问题的办法,能够准确的知道这个问题在我们代码里的哪个未知发生的。
引入 Require 库
使用上面的 guard-let-preconditionFailure 的方案还是有一些冗长,确实让我们呃代码更难驾驭。我们也确实不希望在我们的代码里占很多篇幅去些这种代码,我们想更专注于我们的代码逻辑上。
我的解决方案就是使用 Require。它只是简单的在可选值添加简单的 require() 方法,但能够使得调用的地方更简洁。用这种方法来处理上面加载 JSON 文件的代码就可以这样写:
let configuration = loadConfiguration().require(hint: "Verify that Config.JSON is valid")
当出现异常的时候,会给出下面的错误信息:
fatal error: Required value was nil. Debugging hint: Verify that Config.JSON is valid: file /Users/John/AmazingApp/Sources/AppDelegate.swift, line 17
Require 的另一个优势就是它和调用 preconditionFailure() 方法一样也会抛异常 NSException,就能使得那些异常上报工具能够捕获异常发生时候的元数据。
你如果想在自己代码中使用的话,
所以,总结来看,在 Swift 语言里处理那些非可选的可选值,我有几点自己的贴心小提示给大家:
lazy 属性要比非可选的可选值要更好
适当的依赖管理要比非可选的可选值要好
当你使用非可选的可选值的时候,优雅的崩溃
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具frontopen主题V1.5.04.15版本已发布 推荐更新!
frontopen “讨论区” 正式上线
鸣谢主题捐赠者:感叹帝,Calon YE,孙玉龙,魂客,创想,孜夕寒
顾余笑,小菜,晨风,菠菜,*忠杰,浪子,99开发赞助,IT江湖,小熊
如果发现更新最新版出现缩略图无法显示,请先装回v1.4.03.02版本
swift语言学习笔记
swift语言学习笔记
围观16856次
编辑日期: 字体:
本文仅用于我个人对swift学习记录之用,会不定期更新。至于对你是否有用不敢保证哦。
swift大小写敏感
swift输出方法println()
swift声明变量var 声明常量let
需注意 let常量只能再初始化时进行赋值,var变量可以在任何时候赋值
swift在println中输出多个变量的方法为println(“(val1),(val2),…”) 即在双引号中用(var) 来输出变量
swift对数字整型有Int Int8 Int16 Int32 Int64位几种类型。其中Int会根据当前操作系统自动转换为当前系统位数的整型类型。例如当前系统是32位,则Int 实际上就是Int32
swift获取数据类型范围的方法:以Int整型为例,Int.max为获取该类型的最大值 Int.min为获取该整型的最小值
swift中如果想提高数据可读性的话,可以将1000000写成1_000_000 这样写不会影响程序的执行,又可以提高代码的可读性。
swift设置数据进制:二进制0b
八进制0o 十六进制0x
swift字符串中的转意符 :(null字符) , \(反斜杠),t(制表符),n(新行符),r(回车符),”(双引号),’(单引号)
swift单字节Unicode字符,使用xnn表示,其中nn代表两个十六进制的数
let str = 
输出为“A”
swift双字节Unicode字符,使用unnnn表示,其中nnnn代表4个十六进制数
let str2 = &#”
swift四字节Unicode字符,使用Unnnnnnnn表示,其中nnnnnnnn代表8个十六进制数
let str3 = &#F496”
输出为一个特殊字符
swift字符串大小写转换:
let small_string = “abcd”
let big_string = “ABCD”
println(small_string.uppercaseString)
println(big_string.lowercaseString)
如上所示,.uppercaseString为转化为大写 .lowercaseString为转化为小写
swift中的for循环写法:
for key in value{
println(key)
swift返回字符串长度:countElements(string)
swift返回字符串各字符的unicode字符编码:
for c in string.unicodeScalars{
print(“(c.value)n”)
swift元数组类型的操作方法:
let name = (value1,vlaue2,value3)
其中,值可以引用其他变量或常量
let (var1,var2,var3) = name
可以将之前定义的元数组中的值,赋值给声明的3个变量,并且按顺序一一对应
let (_,var2,_)=name
如果只取其中某一个,或者多个值时,不需要的的值需要用下划线代替
let name = (var1:value1,var2:value2,var3:value3)
可以在定义元数组时给元素命名,使用时只需要name.var1 调用即可。与javascript非常相似
swift中的nil通过包含另一个值或者包含nil来指明该值不存在。通过在类型后面添加问号(?)来标记一个值为可选值。例如:var value1:Int?=nil 设置一个可选值。当然,默认情况下,在表达式后加上问号将会自动为变量设定nil值,例如:var value2:Int?
但是需要注意,nil只能赋值给optional类型(即可选类型)。不能直接赋值给非可选类型,例如:var value:Int = nil 这样是错误的。
可选类型的值,访问时需要再转换后的变量后加上! 才可以单独调出可选值中的内容。如下例所示:
var str = 
var num:Int? = str.toInt()
var num2 = num! + <span style="color: #
demo中,将字符串str的123转换为Int数字整型,转化为成功后,变量num的实际内容为{some,123} 此时如果使用print打印的画,不会有任何问题。但是不能直接用于计算,如上例:num2中 如果num后没有! 则会报错。因此这里可以理解为,带有可选值的变量后跟上一个!可以将可选值中的有效值提出,并进行计算。
swift自定义类型:
typealias ID = UInt8//自定义类型ID
var max = ID.max //查询类型ID的最大范围
var id:ID = 20; //将id变量的类型设置为ID并将值设置为20.如果超出范围会报错
swift 类型转换:
字符型String 转换为 整型Int时使用 .toInt()方式。如下例子
var str_num:String = &#&#8221;
var int_num:Int? = str_num.toInt()
将字符类型变量str_num转换为Int类型并赋值给int_num。这里需要注意的时,如果给int_num指定类型的话,必须在类型后面加上?即可选值。因为字符串不确定性很多,很多情况下转化为Int类型时会带有字符。因此需要为其设置可选值,当转换的字符串型中包含字符时,会显示nil。一般情况下如果不需要给变量指定类型的话,可以不需要加?
例如:var int_num = str_num.toInt()
其他类型转换为字符串型使用toString()的内置方法。如下例子
var int_num2 = 123456
var str_num2 = toString(int_num2)
//转化为字符串&#&#8243;
var str_num3 = toString(true) //将布尔型转换为字符串true
运算时得数据类型转换,简单得记忆方式为,需要转换得类型(变量)。例如要转化为int16类型,则:Int16(int_num2)
如果要转化为Float类型则为:Float(int_num2)
下面列几个数据转换与计算时得一些特性,如下:
var str:Int8 = <span style="color: #
var str2:Int16 = <span style="color: #
var str3:Int16 = Int16(str) + str2
str为Int8类型,str2为Int16类型。如果两个数字相加的时候,必须先将str转换为Int16格式再相加。因为swift为了避免精度的丢失,需要显式的将Int8类型转换为相同的类型。注意!这里不能将str2转换为Int8格式进行计算。
简单的记忆方法为,可以大转小,不能小转大。
var intNum:Int = <span style="color: #
var floatNum = <span style="color: #
var tol = intNum + Int(floatNum)
上述例子中,是一个整型与浮点型之间的运算。其中intNum为Int类型,floatNum为Double类型。如果两个类型进行相加的画,必须将其中一个类型转换为另外一个数据的类型才能正常运算。例中将floatNum转换为Int类型,转换并进行计算后结果为101。说明floatNum通过类型转换后,将小数点后的数据全部舍弃,使floatNum的值变为1。而变量tol如果不指定任何类型的画,会自动转换为右侧表达式中,正常计算的类型。
swift中空字符串的声明方式为:var str = &#8220;&#8221; 或者 var str = String()
判断字符串是否为空的属性为 .isEmpty 使用该属性后,结果以布尔型输出
swfit数组的基本语法为[value1,value2,value3,&#8230;..]
swift中数组声明时可以为数组指定类型,也可以不为数组指定类型。
var gril = [&#8220;hanmeimei&#8221;,30,&#8220;teacher&#8221;]
声明的gril数组中包含字符串和数字整型,由于数组没有指定相应的内容类型,因此这样写时合法的。
而如下例:
var gril:String[] = [&#8220;hanmeimei&#8221;,30,&#8220;teacher&#8221;]
声明数组时,为数组内容指定了String类型。如果这样设置的话,程序就会报错。因为其中30时整型类实数,如果一定声明类型的话,请务必将数组的内容转换为同一类型。
swift追加与删除数组元素的方法如下例:
var gril = [&#8220;hanmeimei&#8221;,&#21;,&#8220;teacher&#8221;]
gril.append(&#8220;china&#8221;)
//使用append方法,该方法在数组最后追加一个元素
gril.insert(&#8220;female&#8221;,atIndex:1)
//使用insert方法,该方法时在数组的指定位置插入一个值。0为起始位置
gril += [&#8220;is mother&#8221;,&#8220;has one children&#8221;]
//使用+=的形式拼接数组,拼接的内容会追加到数组的尾部
gril.removeAtIndex(0) //使用removeAtIndex方法,删除第0个数组元素。该方法的返回值是被删除数组元素的内容,可以将该方法赋值给一个新的变量来获取返回的内容,例如:var str = gril.removeAtIndex(0)
这时候str的值为&#8221;hanmeimei&#8221;
gril.count
//统计数组的元素个数
swfit中遍历数组的方法有两种:
1.for in 例如:
for key in gril{
println(key)
2.有循环变量的遍历方式,可以获得数组的下标,例如:
for (index,value) in enumerate(gril){
println(&#8220;下标为(index),值为(value)&#8220;)
此方法首先使用enumerate方法,将gril数组元素处理为元数组类型,即每次遍历都会对应(index,value)进行赋值
swift中字典的基本语法为:[key1:val1,key2:val2,key3:val3,&#8230;]
var city:Dictionary&String,String& = [&#8220;key1&#8221;:&#8220;wuhan&#8221;,&#8220;key2&#8221;:&#8220;kunming&#8221;,&#8220;key3&#8221;:&#8220;changsha&#8221;]
创建一个city的字典,上例中为字典指定了模版,即Dictionary&String,String& 代表指定字典的key为 字符串格式,val也为字符串格式。在这里为字典的key 和 val设置格式时,需要注意所属类型的范围。
city[&#8220;key4&#8221;] = &#8220;guangzhuo&#8221;
//向字典中追加key4 值为guangzhou
当然了,修改对应键值的内容,也可以使用这种方法,值需要为指定的键赋值即可
字典也可以使用.count属性来获取字典键值的对数
关于swift删除字典的操作方法,用下面的实例来解说:
if let removeValue = city.removeValueForKey(&#8220;key2&#8221;){
println(&#8220;删除的键值为(removeValue)&#8220;)
//打印kunimng
println(&#8220;没有找到对应的&#8221;key2&#8243;的键&#8221;)
上述实例中,使用了removeValueForKey方法。该方法查找key2键,并将其删除,返回其键的值。其中if表达式中,先判断key2是否存在。如果key2存在,返回true,且返回被删除的键值,然后将值赋值给removeValue。
swift对字典的遍历也有两种方法,如下:
1.for in 例如:
for (index,value) in city{
println(&#8220;键(index),值(value)&#8220;)
2.遍历键和值的方法:
for citykey in city.keys{
println(citykey)
for cityname in city.values{
println(cityname)
如上例,遍历key可以使用.keys属性,如果只是遍历值的话可以使用.values属性
实际上,.keys和.values两种属性还可以结合Array()函数将取出的键或值转换为数组,如下:
let cityarray = Array(city.values)
//输出[changsha, guangzhuo, wuhan]
swift分支语句包含以下两种:
if else语句 与其他程序一致,不做介绍。
switch语句,与其他程序有较大的区别,做了很多的优化,此处使用一个实例来说明,如下:
let number = 12
switchnumber{
case 1,2,3,4,5,6,7,8,9,10:
println(&#的数字&#8221;)
case11,12,13,14,15,16,17,18,19,20:
println(&#之间的数字&#8221;)
println(&#8220;数字不在方案范围之内&#8221;)
let number2 = <span style="color: #
switch number2{
println(&#21;)
case 1&#8230;10:
println(&#&#8221;)
case 11&#8230;<span style="color: #:
println(&#&#8221;)
case 101&#8230;1000:
println(&#0&#8221;)
case 1001&#8230;10000:
println(&#000&#8221;)
println(&#8220;不在方案范围内&#8221;)
通过上述两个例子,可以发现swift中的switch语句省去了每个方案的break(实际可以理解为自动加入了break并不显示),切case方案可以为任何类型的值,都可以进行判断。case支持多个值的筛选,如val1,val2,val3,&#8230; 或者 值的范围筛选,如n1&#8230;n2
swift的循环语句包含四种:
1.while 语句,与其他程序语句相同,不做介绍
while <span style="color: # & i {
println(i)
2.do while语句
println(n)
}while<span style="color: #&n
3.for 循环
for var i=0; i&<span style="color: #; i++ {
println(&#8220;数字(i)&#8220;)
4.for in 循环 主要用于遍历
//1.遍历范围
for index in 1&#8230;5{
println(index)
//2.忽略循环变量,仅用于计算变量,不过一般这种情况更适合用for或者while来处理
let base = 3
let round = 20
var point = 1
for _ in 1&#8230;round{
point *= base
println(&#8220;point是(point)&#8220;)
//3.遍历数组
let array = [&#8220;val1&#8221;,&#8220;val2&#8221;,&#8220;val3&#8221;]
for key in array{
println(key)
//4.遍历字典
var city:Dictionary&String,String& = [&#8220;key1&#8221;:&#8220;wuhan&#8221;,&#8220;key2&#8221;:&#8220;kunming&#8221;,&#8220;key3&#8221;:&#8220;changsha&#8221;]
for (index,value) in city{
println(&#8220;键(index),值(value)&#8220;)
//5.遍历字符串
var str2 = &#8220;swift&#8221;
for key in str2{
println(key)
swift跳转语句
1.continue语句
continue实例,终止当前循环,并执行下面的循环
for var i = 0; i&<span style="color: #; i++ {
if i%10 == 0{
println(i)
2.break语句
break实例,终止当前循环,并结束剩余的循环
for var i = 0; i&<span style="color: #; i++ {
if i == 10{
println(i)
3.fallthrough语句
可以让switch语句中的方案选择继续贯穿下去,类似于其他语言中,case语句后没有加break的效果。
let number2 = <span style="color: #
switch number2{
println(&#21;)
case 1&#8230;10:
println(&#&#8221;)
case 11&#8230;<span style="color: #:
println(&#&#8221;)
case <span style="color: #&#8230;<span style="color: #:
println(&#0&#8221;)
fallthrough//让方案匹配继续贯穿下去
case <span style="color: #&#8230;<span style="color: #:
println(&#000&#8221;)
println(&#8220;不在方案范围内&#8221;)
4.return语句
一般多用于函数中的返回值所用,和其他程序基本类似,不做介绍
swift函数的定义方式,如下实例:
1.无值返回函数
func ourput(name:String,put:String) {
println(&#8220;名字(name),输出(put)&#8220;)
2.有值返回函数
func ourput(name:String,put:String) -& String {
println(&#8220;名字(name),输出(put)&#8220;)
return name+put
函数参数后面的-&String是设定返回函数的类型,如果指定了类型则必须有return语句,有return语句,则必须为返回值设置类型
3.多值返回函数
func many(in1:String,in2:String,in3:Int) -& (set1:String,set2:String,set3:Int){
var str1 = in1,str2 = in2,num = in3
str1 += str2 + String(num)
return (str1,str2,num)
println(many(&#21;,&#21;,3))
4.嵌套函数
//嵌套函数
func gotheway(Direction:Bool) -& (Int) -& Int {//返回值实际上是嵌套中的函数指针,所以还要为嵌套函数传入的参数设定类型,即(Int)
func gofront(input:Int) -& Int {return input +
func goback(input:Int) -& Int {return input &#8211; 1}
return Direction ? goback : gofront
var currentways = &#8211;4
let movetozero = gotheway(currentways & 0) //由于gotheway为假,所以此时的movetozero实际上是嵌套函数中的gofront。注意,此处的gotheways只能传入布尔类型,因为这个函数只有一个布尔类型的参数。只有为函数传入对应的参数后,gotheways函数才会将嵌套的函数返回给movetozero,此时gofront才能通过movetozero这个函数指针正常工作
whilecurrentways != 0{
println(currentways)
currentways = movetozero(currentways)
本文固定链接:
转载请注明:
作者:品味人生
就是一个管理员,frontopen的管理员,嗯,介绍完毕!
如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!
您可能还会对这些文章感兴趣!}

我要回帖

更多关于 go语言获取文件大小 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信