ก่อนที่ฉันจะอัปเดต xCode 6 ฉันไม่มีปัญหาในการส่งคู่เป็นสตริง แต่ตอนนี้ฉันมีข้อผิดพลาด
var a: Double = 1.5
var b: String = String(a)
มันทำให้ฉันมีข้อความแสดงข้อผิดพลาด "double is not convertible to string" มีวิธีอื่นที่จะทำได้หรือไม่?
ก่อนที่ฉันจะอัปเดต xCode 6 ฉันไม่มีปัญหาในการส่งคู่เป็นสตริง แต่ตอนนี้ฉันมีข้อผิดพลาด
var a: Double = 1.5
var b: String = String(a)
มันทำให้ฉันมีข้อความแสดงข้อผิดพลาด "double is not convertible to string" มีวิธีอื่นที่จะทำได้หรือไม่?
คำตอบ:
ไม่ใช่การแคสต์ แต่เป็นการสร้างสตริงจากค่าที่มีรูปแบบ
let a: Double = 1.5
let b: String = String(format: "%f", a)
print("b: \(b)") // b: 1.500000
ด้วยรูปแบบอื่น:
let c: String = String(format: "%.1f", a)
print("c: \(c)") // c: 1.5
คุณยังสามารถละเว้นformat
คุณสมบัติได้หากไม่จำเป็นต้องจัดรูปแบบ
format:"%.1f" = 1 digit // 1.5
; format:"%.5f" = 5 digits // 1.50000
String(yourDouble)
คุณก็ต้องทำ
let double = 1.5
let string = double.description
อัปเดต Xcode 7.1 • Swift 2.1:
ตอนนี้ Double สามารถแปลงเป็น String ได้ดังนั้นคุณสามารถใช้งานได้ตามที่คุณต้องการ:
let double = 1.5
let doubleString = String(double) // "1.5"
Swift 3 หรือใหม่กว่าเราสามารถขยายLosslessStringConvertible
และทำให้เป็นแบบทั่วไปได้
Xcode 11.3 • Swift 5.1 หรือใหม่กว่า
extension LosslessStringConvertible {
var string: String { .init(self) }
}
let double = 1.5
let string = double.string // "1.5"
สำหรับตัวเลขเศษส่วนคงที่เราสามารถขยายFloatingPoint
โปรโตคอล:
extension FloatingPoint {
func fixedFraction(digits: Int) -> String {
return String(format: "%.*f", digits, self as! CVarArg)
}
}
หากคุณต้องการควบคุมรูปแบบตัวเลขของคุณมากขึ้น (ตัวเลขเศษส่วนต่ำสุดและสูงสุดและโหมดการปัดเศษ) คุณสามารถใช้ NumberFormatter:
extension Formatter {
static let number = NumberFormatter()
}
extension FloatingPoint {
func fractionDigits(min: Int = 2, max: Int = 2, roundingMode: NumberFormatter.RoundingMode = .halfEven) -> String {
Formatter.number.minimumFractionDigits = min
Formatter.number.maximumFractionDigits = max
Formatter.number.roundingMode = roundingMode
Formatter.number.numberStyle = .decimal
return Formatter.number.string(for: self) ?? ""
}
}
2.12345.fractionDigits() // "2.12"
2.12345.fractionDigits(min: 3, max: 3, roundingMode: .up) // "2.124"
String(format: "%.\(digits)f", self as! CVarArg)
ด้วยString(format: "%.*f", digits, self as! CVarArg)
นอกจากคำตอบ @Zaph แล้วคุณสามารถสร้างไฟล์ extension:
extension Double {
func toString() -> String {
return String(format: "%.1f",self)
}
}
การใช้งาน:
var a:Double = 1.5
println("output: \(a.toString())") // output: 1.5
a.toString()
นักพัฒนารายอื่นเห็นว่าจะมีช่วงเวลา WTF แน่นอน
myToString()
เป็นคำจำกัดความที่กำหนดเองได้ แต่เช่นเดียวกับในภาษาอื่น ๆ การสร้างต้นแบบนำไปสู่การหลีกเลี่ยงรหัสซ้ำและการบำรุงรักษาที่ดี
println("output: \(a.toString())")
และprintln("output: \(a)")
. ตัวเลือกที่สองไม่ก่อให้เกิดข้อผิดพลาดในการคอมไพล์ ตัวเลือกนี้เป็นการปฏิบัติที่ไม่ดีหรือไม่?
yourDouble?.toString() ?? ""
Swift 3+:ลองใช้โค้ดเหล่านี้
let num: Double = 1.5
let str = String(format: "%.2f", num)
เพื่อสร้างสตริงใด ๆ อย่างรวดเร็วยกเว้นค่า enum เพียงแค่ทำสิ่งที่คุณทำในเมธอด println ()
ตัวอย่างเช่น:
var stringOfDBL = "\(myDouble)"
Swift 4 : ใช้รหัสต่อไปนี้
let number = 2.4
let string = String(format: "%.2f", number)
ฟังก์ชันนี้จะช่วยให้คุณระบุจำนวนตำแหน่งทศนิยมที่จะแสดง:
func doubleToString(number:Double, numberOfDecimalPlaces:Int) -> String {
return String(format:"%."+numberOfDecimalPlaces.description+"f", number)
}
การใช้งาน:
let numberString = doubleToStringDecimalPlacesWithDouble(number: x, numberOfDecimalPlaces: 2)
String(format:"%."+numberOfDecimalPlaces.description+"f", number)
ด้วยString(format:"%.*f", numberOfDecimalPlaces, number)
มีคำตอบมากมายที่นี่ซึ่งแนะนำเทคนิคต่างๆมากมาย แต่เมื่อนำเสนอตัวเลขใน UI คุณมักต้องการใช้NumberFormatter
เพื่อให้ผลลัพธ์มีการจัดรูปแบบปัดเศษและแปลเป็นภาษาท้องถิ่นอย่างเหมาะสม:
let value = 10000.5
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
guard let string = formatter.string(for: value) else { return }
print(string) // 10,000.5
หากคุณต้องการจำนวนตำแหน่งทศนิยมคงที่เช่นค่าสกุลเงิน
let value = 10000.5
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
guard let string = formatter.string(for: value) else { return }
print(string) // 10,000.50
แต่ความสวยงามของแนวทางนี้ก็คือมันจะถูกแปลอย่างถูกต้องซึ่งส่งผลให้เกิดใน10,000.50
สหรัฐอเมริกา แต่10.000,50
ในเยอรมนี สถานที่ต่างๆมีรูปแบบที่ต้องการสำหรับตัวเลขที่แตกต่างกันและเราควรปล่อยให้NumberFormatter
ใช้รูปแบบที่ผู้ใช้ปลายทางต้องการเมื่อนำเสนอค่าตัวเลขภายใน UI
ไม่จำเป็นต้องพูดในขณะที่NumberFormatter
มีความสำคัญในการเตรียมการแสดงสตริงภายใน UI แต่ก็ไม่ควรใช้หากเขียนค่าตัวเลขเป็นสตริงสำหรับพื้นที่จัดเก็บถาวรอินเทอร์เฟซกับบริการบนเว็บเป็นต้น
ใน 3 อย่างรวดเร็ว:
var a: Double = 1.5
var b: String = String(a)
ใน swift 3 นั้นง่ายมากตามที่ระบุด้านล่าง
let stringDouble = String(describing: double)
"Optional(6.1696108999999995)"
สำหรับฉัน
var b = String(stringInterpolationSegment: a)
สิ่งนี้ใช้ได้กับฉัน คุณอาจได้ลอง
ใน Swift 4 หากคุณต้องการแก้ไขและใช้ Double ใน UI เป็น textLabel "String" คุณสามารถเพิ่มสิ่งนี้ได้ที่ท้ายไฟล์ของคุณ:
extension Double {
func roundToInt() -> Int{
return Int(Darwin.round(self))
}
}
และใช้สิ่งนี้หากคุณต้องการให้มีใน textlabel:
currentTemp.text = "\(weatherData.tempCelsius.roundToInt())"
หรือพิมพ์เป็น Int:
print(weatherData.tempCelsius.roundToInt())
ฉันต้องการแนวทาง NSNumber และ NumberFormatter (ที่ต้องการ) นอกจากนี้คุณสามารถใช้ส่วนขยายเพื่อหลีกเลี่ยงรหัสท้องอืด
extension Double {
var toString: String {
return NSNumber(value: self).stringValue
}
}
คุณยังต้องการวิธีการย้อนกลับ
extension String {
var toDouble: Double {
return Double(self) ?? .nan
}
}
LossLessStringConvertible
โปรโตคอลการขยายแบบทั่วไปแทนการขยาย Double extension LosslessStringConvertible { var string: String { return .init(self) } }
Swift 5 : ใช้รหัสต่อไปนี้
extension Double {
func getStringValue(withFloatingPoints points: Int = 0) -> String {
let valDouble = modf(self)
let fractionalVal = (valDouble.1)
if fractionalVal > 0 {
return String(format: "%.*f", points, self)
}
return String(format: "%.0f", self)
}
}
String(format: "%.\(points)f", self)
ด้วยString(format: "%.*f", points, self)
var b = "\(a)"