-4

I am trying to make a physics app in XCode that will approximate a wavefunction and return the allowed energies. I am new to objects/classes, so I was wondering how to know if I should be using a class or not.

Currently, I have made a class for Wavefunction and one for Potential (the "potential" is just the data from an external file that represents a "field", so to speak). Now I'm wondering if I need to make a class for Constants which will hold all of the arbitrary constants related to physics, such as -2m/hbar^2.

How do I decide if I need this class or not?

Hamish
  • 78,605
  • 19
  • 187
  • 280
loltospoon
  • 239
  • 1
  • 9
  • Related: [Swift constants: Struct or Enum](http://stackoverflow.com/questions/38585344/swift-constants-struct-or-enum) – Martin R Mar 14 '17 at 20:26

2 Answers2

2

You don't need to create a class for constants - just use an enum, which is a simpler, lighter way of representing these static values:

enum PhysicalConstants {
    static let speedOfLight = 299792458         //meters per sec
    static let atomicWeightOfCobalt 58.933195   //u ± 0.000005
}

You can store these in their own file, for example constants.swift, and then you can call these wherever in your code:

let circumference = PhysicalConstants.pi * 2 * r

As for your more general question, the answer depends upon several factors - are there existing objects which have features which will meet your needs? Do you expect you'll be creating an ordered hierarchy of structures that inherit features from each other? Both would suggest objects.

In general, though, Swift, while allowing you to continue using the purely object-oriented approach of traditional cocoa programming, tends to lean away from objects for custom data structures such as the ones you are describing, if you want your solution to be "swifty" (which is to say, safe and easy to read).

IMHO, of course.

jglasse
  • 1,188
  • 12
  • 23
  • 2
    IMO `e` and `pi` would be better placed on types conforming to the `FloatingPoint` protocol (in fact, that's exactly where `pi` is already). But yeah, for things like the speed of light – I agree an `enum` is the way to go. – Hamish Mar 14 '17 at 20:31
  • I agree - somewhat lazy examples, but at the stage indicated by the question, I figured this was an easy way of illustrating the concept. – jglasse Mar 14 '17 at 20:33
  • What is the benefit of an enum (without cases !) over a struct? – vadian Mar 14 '17 at 20:33
  • 1
    @vadian You cannot accidently construct an instance of a caseless `enum` (you could achieve the same with a `struct` with a `private init()`, but that's more effort for the same result). – Hamish Mar 14 '17 at 20:34
  • It's a matter of style. Struct is completely valid, though I prefer enums for flat values. – jglasse Mar 14 '17 at 20:34
  • 1
    @vadian: http://stackoverflow.com/questions/38585344/swift-constants-struct-or-enum. – Martin R Mar 14 '17 at 20:34
  • 1
    @vadian The Swift standard library type [`Never`](https://developer.apple.com/reference/swift/never), for example, is a caseless enum. – rob mayoff Mar 14 '17 at 20:39
  • Got it, thanks @all – vadian Mar 14 '17 at 20:39
2

Would you ever need to create an instance of the Constants class? No. So it shouldn't be a class.

A more fitting way to define your constants would be as static properties of Double, just like pi is defined as a static property of Double.

extension Double {

    // The Dirac constant in Joule-seconds, equal to the Planck constant divided by 2π.
    static let diracConstant = 1.054_571_8e-34 // in Joule-seconds

    // Or you can spell it this way if you want.
    static let hBar = 1.054_571_8-34

    // Or even this way! ħ is Unicode U+0127 LATIN SMALL LETTER H WITH STROKE
    static let ħ = 1.054_571_8e-34

}

Then you can access it explicitly like this:

-2 * m / (Double.diracConstant * Double.diracConstant)
-2 * m / (Double.hBar * Double.hBar)
-2 * m / (Double.ħ * Double.ħ)

Presumably, m is already of type Double, so you can use “dot syntax” to make the expression even shorter:

-2 * m / (.diracConstant *.diracConstant)
-2 * m / (.hBar *.hBar)
-2 * m / (.ħ *.ħ)

Or if you define a square function:

func square(_ x: Double) -> Double { return x * x }

Then you can say this:

-2 * m / square(.diracConstant)
-2 * m / square(.hBar)
-2 * m / square(.ħ)

If you're using Float instead of Double for your calculations, you can do all of this with the Float type instead.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848