基本语法
类型别名
在swift中,可以给类型起别名:
如:
typealias dog = Int //类型别名 Int类型变成了dog类型
var a:dog = 10
var b:Int = 20
print(a+b)
typealias S = String
在上述代码段中,可以知道,a和b的类型是相同的,我们定义的dog本质上就是Int类型
note:在swift中,类型可以不声明
字符串拼接
let c:S = "hello"
var d:String = "world"
print(c+d)
var a = 10
print("值等于="+String(a))
print("值等于="+String(1.5))
print("值等于="+String(true))
在上述代码中,可以得知,String类型和String类型可以直接拼接,但是如果一个String类型想和其他基本类型进行拼接则需要进行类型转换,可以使用String(xxx)进行强制类型转换,也可以使用swift中特有的拼接语法进行拼接,如:
print("值等于 = (xxx)")
注意:()这样的转换语法只能在字符串即双引号""包裹内才能生效,即使将(xxx)写在外部拼接也需要加双引号包裹
Swfit ?? 语法 (合并空值运算符)
var a = "10asd"
var c = Double(a) ?? 0 //问号语法,ss如果能转换则转换m,不能则使用后面的值
上述语法定义了一个字符串a,在第二行中使用Double进行强制转换,显然这是行不通的,如果无法转换则会将0赋值给c,但是如果可以转换,则会将转换后的值赋值给c
可选类型和叹号语法
var a:Int? = 10;
var b:Int? = nil;
var c:String? = "Hello"
print(a!)//叹号语法
print(c!)
在上述代码中,定义了abc,在类型后面紧跟一个?表示这个类型的值可以是nil,或是并未赋值,若确定这个变量是有值的,则应该使用(变量名!)的方式取出这个值,否则将无法输出准确的值
if else语法
var value:String? = "hello world"
var a:Int? = 10
if a==nil{
print("a = nil")
}else{
print("a = (a!)")
}
这里不做过多赘述,swfit中的if else语法和其他语言并无二致,只是if后的小括号()可以省略直接写表达式
元组类型
元组类型可以封装不同的数据,在一个类型中
var a = (1,15.6,"hello",true) //直接定义元组类型
var b:(Int,String) = (10,"wsift") //在定义变量的时候就规定元组类型
print(a)
print(b)
var c = () //定义一个空元组c
print(c)
注意:可以直接定义一个空元组,但是如果定义了元组的类型就不能赋一个空元组
var a = (1,15.6,"hello",true) //直接定义元组类型
print(a.0)
print(a.1)
print(a.2)
print(a.3)
若要取出元组中的值,可以使用元素名加下标的方式
元组元素的修改
var a = ("hello",true)
a.0 = "world"
print(a)
如果元组是用var定义的变量则可以改变元组内的元素,如果是let则不行
元组的值传递
var a = ("hello",true)
var b = a
b.0 = "world"
print(a)
print(b)
a:("hello", true)
b:("world", true)
如上所述,将a元组赋值给b元组传递的是值而不是引用,更改元组b并不会影响到元组a
通过名称取出元组的值
var a = (name1:"hello",name2:true)
print(a.name1)
//简洁语法
var (name3,name4) = ("swift",100)
print(name3,name4)
你甚至可以在声明元组类型的时候就定义元组的名称
var a:(name1:Int,name2:String) = (100,"Hello")
print(a.name1)
print(a.name2)
可选项绑定
var a:Int? = 10 //可选参数a,现在有一个值为10
if let value = a //如果参数a有值则将值赋给常量value,并执行if语句
{
print(value)
}
else//如果a没有值,则执行else语句
{
print("没有值")
}
在可选绑定中,if let value = a 这个语句不需要使用a!解析,swift会自动解析值
Switch case 和 fallthrough穿透效果
var a = 10
switch a {
case 10:
print("情况1")
//fallthrough //打开这行代码实现switch穿透
case 20:
print("情况2")
default:
print("没有匹配")
}
**在swift中,switch默认是没有穿透效果的,即在case匹配成功后不会执行下一个case,若想要穿透效果可以在case下跟fallthrough关键字。
区间运算符
var a = 1...4
print("范围 = (a)")
var b = 1..<4
print("范围 = (b)")
var c = -1...4
print("范围 = (c)")
var e = 0...
print(e) //0到无限大的半开区间
for循环
for index in (0...5)
{
print(index)
}
//包括开头不包括结尾
for index in stride(from: 0, to: 10, by: 2)
{
print(index)
}
//包括结尾
for index in stride(from: 0, through: 10, by: 2){
print(index)
}
//反向遍历
for index in stride(from: 0, through: 10, by: 2).reversed(){
print(index)
}
//跳过步数为2的循环
for index in (0...5){
if(index==2)
{
continue
}
print(index)
}
//循环到2结束
for index in (0...5){
if(index==2)
{
break
}
print(index)
}
注意:stride规定开始结尾和步长,to的遍历不包含结尾,through的遍历包含结尾,reversed函数可以使for循环从结尾向开始结尾
String基础操作
添加、包含、插入
var str = "ABCDEF"
//取出str长度
print(str.count)
//判断str是否包含123
print(str.contains("123"))
//判断前缀是否包含
print(str.hasPrefix("A"))
//判断后缀是否包含
print(str.hasSuffix("DEF"))
//插入字符串
str.append("abcde")
//从str中的第三个下标开始插入hello
str.insert(contentsOf: "hello", at: str.index(str.startIndex, offsetBy: 3))
添加
var str = "ABCDEF"
//将str的下标1赋值给index1
let index1 = str.index(str.startIndex,offsetBy: 1)
//将str的下标3赋值给index2
let index2 = str.index(str.startIndex,offsetBy: 3)
//range区间
let range = index1...index2
//将区间内的字符替换成123123
str.replaceSubrange(range, with: "123123")
print(str)
var str = "ABCDEF"
//将str中的BC替换成888
str.replacingOccurrences(of: "BC", with: "888")
print(str)
删除
//删除下标为2的字符
var str = "ABCDEF"
str.remove(at: str.index(str.startIndex, offsetBy: 2))
print(str)
遍历
for item in str{
print(item)
}
多行文本
var value = """
hello
swift
world
"""
print(value)
注意:三个引号中包裹的格式也会被输出
Array数组的基本操作
数组的遍历
var a = [1,2,3,4]
print(a)
var b:[String] = ["hello","world"]
print(b)
var c:Array<Double> = [3.2,3.14,23.2]
print(c)
print(c[0])
数组的替换
var array = ["hello","world","swift"]
//将数组的第0号元素替换
array.replaceSubrange(0..<1, with: ["macOS","ios"])
print(array)
数组的添加
var array = ["hello","world","swift"]
//直接使用加号的方式向数组末尾添加元素
array = array+["ios","macOS"]
print(array)
//========================================
var array = ["hello","world","swift"]
//使用append的方式向数组末尾添加元素
array.append("macOS")
print(array)
数组的插入
var array = ["hello","world","swift"]
//在1下标插入aaa
array.insert("aaa", at: 1)
print(array)
数组的删除
var array = ["hello","world","swift"]
//将元素的0号元素删除
array.remove(at: 0)
print(array)
数组的元素修改
var array = ["hello","world","swift"]
//将索引为1的元素修改为ios
array[1] = "ios"
print(array)
元素的查找
var array = ["hello","world","swift"]
array.contains("hello")
Set集合数组的基本操作
Set数组的定义
var a:Set = [1,2,3,4]
print(a)
var b:Set<String> = ["hello","world"]
print(b)
var c:Set<Int> = []
print(c)
基本操作
var a:Set = ["hello","world","swift"]
//打印数组长度
print(a.count)
//数组末尾插入abc
a.insert("abc")
print(a)
//判断数组是否包含hello
print(a.contains("hello"))
//删除数组中的hello元素
a.remove("hello")
合并数组(去除重复)
var a:Set = ["hello","world","swift"]
let b:Set = ["iphone","android","ios","swift"]
//将a集合和b集合合并成c集合并去除重复的元素
var c = a.union(b)
print(c)
返回两个集合中相同的元素
var a:Set = ["hello","world","swift"]
let b:Set = ["iphone","android","ios","swift"]
//返回两个集合中相同的元素
var c = a.intersection(b)
print(c)
返回两个集合中不同的元素
var a:Set = ["hello","world","swift"]
let b:Set = ["iphone","android","ios","swift"]
//返回两个集合中不同的元素
var c = a.symmetricDifference(b)
print(c)
比较第一个Set和第二个Set中不同的数据
let b:Set = ["iphone","android","ios","swift"]
//比较两个Set,返回前面Set中与后面Set中不同的数据
var c = a.subtracting(b)
print(c)
判断两个集合是否相等
var a:Set = [1,2,3,3]
var b:Set = [3,2,1]
if a==b {
print("两个集合相等")
}else{
print("两个集合不等")
}
注意:这两个Set集合是相等的,因为Set集合是无序无重复的。
Set集合的遍历
var a:Set = ["A","B","C","D"]
//因为Set集合是无序的,所以不能使用数组下标的方式取值
for item in a {
print(item)//遍历出来的顺序是不确定的(底层可能按照一定的算法排序,如:红黑二叉树)
}
数组的过滤
var a:Set = ["A","B","C","D"]
var b = a.filter({(item)->Bool in
if(item == "B" || item == "D"){
return false
}else{
return true
}
})
print(b)
Dictionary集合(类似Map集合)
数组的定义
//范型中的第一项指定Key的类型,第二项指定value的类型
var a:Dictionary<String,String> = ["a":"A","b":"B","c":"C"]
print(a)
//这里直接在数组中定义键值对
var b:[Int:String] = [1:"A",2:"B"]
print(b)
//这里使用了自动判断类型
var c = [1:"hello"]
print(c)
取值
var a:Dictionary<String,String> = ["a":"A","b":"B","c":"C"]
//因为键可能不存在,所以需要从可选类型中取出值,以下是断言a存在
print(a["a"]!)
//一下是如果不存在则输出0
print(a["a"] ?? 0)
修改
var a:Dictionary<String,String> = ["a":"A","b":"B","c":"C"]
//如果有a这个key就会修改key的值,如果没有这个key的话则会将这个键值对添加到集合中
a.updateValue("swift", forKey: "a")
print(a)
删除
var a:Dictionary<String,String> = ["a":"A","b":"B","c":"C"]
//通过键值对删除
a.removeValue(forKey: "a")
过滤器
var a:Dictionary<String,String> = ["a":"A","b":"B","c":"C"]
var b = a.filter({(key,value) -> Bool in
if(key == "b") //此处的条件可以是key也可以是value
{
return false
}
else
{
return true
}
})
print(b)
字典遍历
var a:Dictionary<String,String> = ["a":"A","b":"B","c":"C"]
//这里的key和value只是参数名,可以随便定义,他会将字典中的key赋值给第一项,value给第二个参数
for (key,value) in a
{
print("key = "+key + "value="+value)
}
方法(函数)的调用和定义
func test()// 没有定义返回值
{
print("test()")
}
test()
func test2() -> Int //定义了int类型的返回值
{
return 996
}
print(test2())
func test3(name:String)->String//定义了String类型的参数和String类型的返回值
{
return name
}
print(test3(name: "hello World"))
func test4(name:String...)//定义了一个String类型的可变参数
{
for item in name
{
print(item)
}
}
test4(name: "a","b")
func test5(name:(n1:String,n2:Int))->(String,Int)//定义了元组类型的参数和元组类型的返回值(元素类型也被确定了)
{
var value:(a:String,b:Int)
value.a = name.n1 + "world"
value.b = name.n2 + 10
return value
}
var value = test5(name: (n1: "hello", n2: 20))
print(value)
外部名称和外部名称
//outname是给外部用的提示参数,可以省略,但是内部名称inname不能省略
func test2 (outname inname:String)
{
print(inname)
}
test2(outname: "996")
//下划线_使外部名称省略,直接传值,但是inname不能使用_代替
func test2 (_ inname:String)
{
print(inname)
}
test2("996")
Assert断言
func play(param:Int)
{
if (param<10) {//这里的条件也可以换成type of 判断类型
assert(false,"停止运行")
}
print("值 = " + String(param))
}
play(param: 1)
in out关键字
func test(param:inout Int)//添加了inout关键字就可以直接操作param
{
param = param*2
print(param)
}
var a = 10
print("传递前=" + String(a))
test(param: &a)//参数要加&符号,代表传递引用。 param等价于a
print("传递后=" + String(a))
函数类型
函数类型的定义
//定义函数类型
var a:() -> Void //无参数无返回值类型
var b:(Int,String)->String //Int,String类型的参数返回一个String类型的返回值
let c:([Int]) -> (Int,String)//Int数组类型的参数,返回一个元组
函数类型的使用
//有函数名的定义
func test1() -> Void
{
print("test1()")
}
var a:() -> Void = test1 //将test1赋值给函数类型
a()//函数类型的使用
//=====================================
//匿名函数的方式定义
var b:() -> Void = {
()->Void in
print("匿名函数")
}
b()
//=====================================
一个函数作为参数传入另一个函数
func test(){
print("test()函数,没有参数,没有返回值")
}
func test1(param:()->Void)
{
param()
}
test1(param:test)//test1中的参数就是符合要求的test函数,当然你也可以用匿名的方式传入这个参数
//=========================================
func test1(param:()->Void)
{
param()
}
test1(param:{()->Void in //使用匿名函数的方式传入这个参数
print("匿名函数,没有参数,没有返回值")
})
返回值是函数的函数
func play1(value:Int)->Int
{
return value*value
}
func play2(value:Int)->Int
{
return value+value
}
func test(param:Bool)-> (Int)->Int
{
return param ? play1 : play2
}
var a = test(param: true)
print(type(of: a))
print(a(2))
内嵌函数
内嵌函数就是将函数的返回值(也是一个函数)写在函数体内,供该函数直接使用
func test(param:Bool)-> (Int)->Int
{
func play1(value:Int)->Int
{
return value*value
}
func play2(value:Int)->Int
{
return value+value
}
return param ? play1 : play2
}
var a = test(param: false)
print(type(of: a))
print(a(3))
匿名函数的简写
var a:() -> Void = { ()->Void in
print("没有参数,没有返回值的匿名函数")
}
var b:() -> Void = { //这里简写了()->Void in
print("无参数无返回值的匿名函数的简写")
}
在上述情况中,a和b其实是等价的
枚举类型
enum TestEnum
{
case A
case B
case C
}
func play(param:TestEnum)
{
if(param == TestEnum.A)
{
print("a")
}
if(param == TestEnum.B)
{
print("b")
}
if(param == TestEnum.C)
{
print("c")
}
}
play(param: TestEnum.A)
给枚举类型赋值 取值
enum TestEnum:Int
{
case A = 1
case B = 2
}
print(TestEnum.A)//这样获取枚举值===》A
print(TestEnum.B)
print(TestEnum.A.rawValue)//这样获取原始值 ===》1
print(TestEnum.B.rawValue)
枚举类型的使用
enum TestEnum
{
case name(String)
case age(Int)
case xy(Int,Int)
}
func play(param:TestEnum)
{
switch param {
case TestEnum.name("hello"):
print("hello")
case TestEnum.age(10):
print(10)
case TestEnum.xy(100, 200):
print(100,200)
default:
print("没有匹配")
}
}
play(param: TestEnum.name("hello"))
枚举类型的遍历
enum TestEnum:CaseIterable//case值的迭代器
{
case A
case B
case C
}
print(type(of: TestEnum.allCases))//==>Array<TestEnum>
//第一种遍历方式
for item in TestEnum.allCases {
print(item)
}
print()
//第二种遍历方式
for index in (0..<TestEnum.allCases.count) {
print(TestEnum.allCases[index])
}
结构体
结构体的初始化和使用
struct Student
{
var name = "unknow"
var age = 0
var score = 0.0
var isPass = false
static var schoolName = "大学" //静态的属性不属于某一个实例,不能通过实例,只能通过结构体的名称调用
init()//无参构造
{
}
init(name:String,age:Int,score:Double) //有参构造
{
self.name = name
self.age = age
self.score = score
if(score<60)
{
self.isPass = false
}
self.isPass = true
}
func getName() -> String {
return self.name
}
func getAge() -> Int {
return self.age
}
func getScore() -> Double {
return self.score
}
func getIsPass() -> Bool {//必须加上mutating这个关键字才能在结构体中的函数修改结构体的属性值
return self.isPass
}
mutating func setSocre(score:Double) -> Bool {
self.score = score
if(score<60){
self.isPass = false
}
else{
self.isPass = true
}
return self.isPass
}
}
var a = Student() //创建结构体的实例(使用空构造器)
print(a)
var b = Student(name: "尹锐", age: 20, score: 66.66)
print(b)
print("姓名 = "+b.getName()+",年龄 = (b.getAge()),"+"分数 = "+String(b.getScore())+"是否通过:"+String(b.getIsPass())+"学校 = (Student.schoolName)")
b.setSocre(score: 10)
print(b)
结构体的实例是值传递
struct Test
{
var age = 10
}
var t1 = Test()
print(t1.age) //10
var t2 = t1
print(t2.age) //10
t2.age = 100
print(t1.age) //在结构体中10就算t2的值改变t1也不会受影响
print(t2.age)//100
结构体的注意点
struct Test
{
var a = 10
let b = 100
}
let t1 = Test()//let使实例为常量
print(t1.a)
print(t1.b)
t1.a = 200//t1这个实例是常量,不能更改值
print(t1.a)
结构体的get、set重写和属性计算
struct Person
{
private var value = ""
var name:String
{
set(param)
{
print("set - "+param)
}
get
{
print("get - ")
return value + "ios"
}
}
init()
{
}
}
var person = Person()
person.name = "swift"
print(person.name)
属性观察(属性监听)
import UIKit
struct Person
{
var name:String = "unknow"
{
willSet(new_value)
{
print("willSet - "+new_value) //这一行代码会执行,并输出最新的值(“hello”)
}
didSet(old_value)
{
print("didSet - "+old_value)//这一行代码会执行,并输出最新值之前的值(“unknow”)
}
}
}
var person = Person()
person.name = "hello"
Subscript下标语法
struct Person
{
private var array:[String] = ["swift","ios","macos"]
subscript(index:Int) -> String
{
set(new_value)
{
array.insert(new_value, at: index)
}
get
{
return array[index]
}
}
}
var person = Person()
person[0] = "hello"
print(person[0])
类
类的定义和使用
class Student //类的定义
{
private var name:String = ""
private var age:Int = -1
private var score:Double = -1.0
private var isPass:Bool = false
public static var schoolName = "绍兴职业"
convenience init()//如果想在一个构造器中调用另一个构造器,需要加上convenience这个关键字
{
self.init(name:"unknow",age:0,score:0.0)
}
init(name:String,age:Int,score:Double) //有参构造
{
self.name = name
self.age = age
self.score = score
isPass(score: score)
}
private func isPass(score:Double)
{
if(score<60)
{
self.isPass = false
}
else{
self.isPass = true
}
}
func getName() -> String {
return self.name
}
func getAge() -> Int {
return self.age
}
func getScore() -> Double {
return self.score
}
func getIsPass() -> Bool {
return self.isPass
}
public func setScorre(score:Double) {
self.score = score
isPass(score:score)
}
}
var s1 = Student(name: "阿锐", age: 20, score: 66)
print(s1.getName())
print(s1.getAge())
print(s1.getScore())
print(s1.getIsPass())
print("--------------------------")
var s2 = Student(name: "阿r", age: 18, score: 1)
print(s2.getName())
print(s2.getAge())
print(s2.getScore())
print(s2.getIsPass())
print()
s2.setScorre(score: 61)
print(s2.getIsPass())
类的实例传递的是引用
class Student
{
var name = "hello"
}
var s1 = Student()
print(s1.name)
var s2 = s1
print(s1.name) //-->hello
print(s2.name) //-->hello
//在类中,两个实例其实是指向同一个引用的,改变任意一个实例都会改变引用
s2.name = "world"
print()
print(s1.name) //-->world
print(s2.name) //-->world
类的变量和常量
class Student
{
var name = "hello"
}
let s1 = Student()
//即使实例是常量也能改变属性值(属性必须是变量才能改变)
s1.name = "world"
print(s1.name) //-->world
Any和AnyObject
class Person
{
var name:String
init(name:String)
{
self.name = name
}
}
struct Data
{
var data:String
init(data:String) {
self.data = data
}
}
var a:Any = 1
var b:Any = true
var c:Any = "asdjgjuiosd"
var d:Any = Person(name: "sdiug")
var e:Any = Data(data: "osjng")
var f:AnyObject = Data(data: "oswdihj") //->会报错,AnyObject不能被别的类型赋值,只能被class类型赋值
//any可以被任何类型赋值
print(type(of: a)) //-->Int
print(type(of: b)) //-->Bool
print(type(of: c))//-->String
print(type(of: d))//-->Person
print(type(of: e))//-->Data
类的继承
class Person
{
//private修饰,只能在类的内部使用
private var name:String
private var age:Int
init(name:String,age:Int) {
self.name = name
self.age = age
}
public func setName(name:String)
{
self.name = name
}
public func setAge(age:Int)
{
self.age = age
}
public func getName()->String
{
return self.name
}
public func getAge()->Int
{
return self.age
}
}
//这样Student类就继承了Person类,拥有Person类的所有公共属性和方法,同时也可以在Student类中定义其他的方法
class Student: Person
{
}
var person = Person(name: "person", age: 18)
print(person.getName())
print(person.getAge())
print("----------------------")
var student:Person = Student(name: "student", age: 20)//此处用了多态的写法
print(student is Student)//这行代码用来判断student是不是Student类型的,返回true
print(student.getName())
print(student.getAge())
向下类型转换
var student:Person = Student(name: "student", age: 20)
let s = student as! Student //这里确定student属于Student类型,可以直接转型
方法重载
class Student: Person
{
func play(param:String)
{
print(param)
}
func play(param:Int)//参数类型不同,实现了方法重载
{
print(param)
}
}
方法重写
class Person
{
//private修饰,只能在类的内部使用
var name:String
var age:Int
init(name:String,age:Int) {
self.name = name
self.age = age
}
public func setName(name:String)
{
self.name = name
}
public func setAge(age:Int)
{
self.age = age
}
public func getName()->String
{
return self.name
}
public func getAge()->Int
{
return self.age
}
}
class Student:Person
{
//这里对属性的get和set方法进行了重写,使得属性的set和get有了自己独有的功能
override var name: String{
set
{
super.name = super.name+"- student"
}
get
{
return super.getName()
}
}
override init(name: String, age: Int)
{
super.init(name: "锐", age: 20)//在子类重写父类初始化器之前需要先实现父类的初始化器
self.name = name
}
}
var stu = Student(name: "1", age: 10)
print(stu.getName()) //-->"1- student"
对象的相等性判断
class A
{
}
var t1 = A()
var t2 = A()
var t3 = t1
print(t1 === t3) //-->true
print(t1 === t2) //-->false
类型判断、转型
import UIKit
class A
{
}
class B:A
{
var name:String
init(name:String)
{
self.name = name
}
func printName() {
print("this is B name = " + self.name)
}
}
class C:A
{
var name:String
init(name:String)
{
self.name = name
}
func printName() {
print("this is C name = " + self.name)
}
}
func getObject(param:Int) -> A
{
if(param>10)
{
return B(name: "小B")
}else
{
return C(name: "小C")
}
}
var obj = getObject(param: 15)//这里的obj其实是多态的写法,如下:var obj:A = getObject(param: 15),因为A中没有printName所以要造型
if(obj is B) //判断obj是什么类型的,解析并使用printName方法
{
let p = obj as! B
p.printName()
}
else
{
let p = obj as! C
p.printName()
}
类的扩展extension
class A
{
}
//以下代码扩展了A类
extension A //要扩展一个类需要用到extension关键字
{
var name:String
{
get
{
return "hello world"
}
}
func toString(){
print("this is A toString")
}
}
var a = A()
print(a.name) //-->hello world
a.toString() //-->this is A toString
泛型
//<T>这里的T可以是任意的字母,通常用T表示泛型,如果在<>中写死了某种类型那么参数只能是这种类型,如:<Int>
func toString<T>(param:T)->T //<>中的类型规定了参数类型,返回值类型可以是泛型也可以是其他类型
{
return param
}
协议protocol(interface)
import UIKit
class TestClass
{
}
protocol Protocol1 { //定义了协议,协议中没有任何功能实现,只是规定了协议
var value1:String{set get} //可读、可写
func play1() -> String
}
protocol Protocol2 {
var value2:String{get}//只读属性
func play2() -> String
}
class Data:TestClass,Protocol1,Protocol2 //Data类继承了TestClass类,实现了两个接口
{
var value1: String
var value2: String //虽然协议中规定了values是只读的属性,但是你却可以在实现类中使该实例是可写的甚至可以定义这个实例为常量
{
get
{
return "value2"
}
}
init(value1:String) {
self.value1 = value1
}
func play1() -> String
{
return self.value1
}
func play2() -> String {
return self.value2
}
}
var data = Data(value1:"hello")
print(data.play1()) //-->hello
print(data.play2()) //-->value2